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/x87/assembler-x87.h"
38 
39 #if V8_TARGET_ARCH_X87
40 
41 #include "src/base/bits.h"
42 #include "src/base/cpu.h"
43 #include "src/disassembler.h"
44 #include "src/macro-assembler.h"
45 #include "src/v8.h"
46 
47 namespace v8 {
48 namespace internal {
49 
50 // -----------------------------------------------------------------------------
51 // Implementation of CpuFeatures
52 
ProbeImpl(bool cross_compile)53 void CpuFeatures::ProbeImpl(bool cross_compile) {
54   base::CPU cpu;
55 
56   // Only use statically determined features for cross compile (snapshot).
57   if (cross_compile) return;
58 }
59 
60 
PrintTarget()61 void CpuFeatures::PrintTarget() { }
PrintFeatures()62 void CpuFeatures::PrintFeatures() { }
63 
64 
65 // -----------------------------------------------------------------------------
66 // Implementation of Displacement
67 
init(Label * L,Type type)68 void Displacement::init(Label* L, Type type) {
69   DCHECK(!L->is_bound());
70   int next = 0;
71   if (L->is_linked()) {
72     next = L->pos();
73     DCHECK(next > 0);  // Displacements must be at positions > 0
74   }
75   // Ensure that we _never_ overflow the next field.
76   DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize));
77   data_ = NextField::encode(next) | TypeField::encode(type);
78 }
79 
80 
81 // -----------------------------------------------------------------------------
82 // Implementation of RelocInfo
83 
84 
85 const int RelocInfo::kApplyMask =
86     RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
87     1 << RelocInfo::INTERNAL_REFERENCE | 1 << RelocInfo::CODE_AGE_SEQUENCE |
88     RelocInfo::kDebugBreakSlotMask;
89 
90 
IsCodedSpecially()91 bool RelocInfo::IsCodedSpecially() {
92   // The deserializer needs to know whether a pointer is specially coded.  Being
93   // specially coded on IA32 means that it is a relative address, as used by
94   // branch instructions.  These are also the ones that need changing when a
95   // code object moves.
96   return (1 << rmode_) & kApplyMask;
97 }
98 
99 
IsInConstantPool()100 bool RelocInfo::IsInConstantPool() {
101   return false;
102 }
103 
wasm_memory_reference()104 Address RelocInfo::wasm_memory_reference() {
105   DCHECK(IsWasmMemoryReference(rmode_));
106   return Memory::Address_at(pc_);
107 }
108 
wasm_global_reference()109 Address RelocInfo::wasm_global_reference() {
110   DCHECK(IsWasmGlobalReference(rmode_));
111   return Memory::Address_at(pc_);
112 }
113 
wasm_memory_size_reference()114 uint32_t RelocInfo::wasm_memory_size_reference() {
115   DCHECK(IsWasmMemorySizeReference(rmode_));
116   return Memory::uint32_at(pc_);
117 }
118 
unchecked_update_wasm_memory_reference(Address address,ICacheFlushMode flush_mode)119 void RelocInfo::unchecked_update_wasm_memory_reference(
120     Address address, ICacheFlushMode flush_mode) {
121   Memory::Address_at(pc_) = address;
122 }
123 
unchecked_update_wasm_memory_size(uint32_t size,ICacheFlushMode flush_mode)124 void RelocInfo::unchecked_update_wasm_memory_size(uint32_t size,
125                                                   ICacheFlushMode flush_mode) {
126   Memory::uint32_at(pc_) = size;
127 }
128 
129 // -----------------------------------------------------------------------------
130 // Implementation of Operand
131 
Operand(Register base,int32_t disp,RelocInfo::Mode rmode)132 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
133   // [base + disp/r]
134   if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
135     // [base]
136     set_modrm(0, base);
137     if (base.is(esp)) set_sib(times_1, esp, base);
138   } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
139     // [base + disp8]
140     set_modrm(1, base);
141     if (base.is(esp)) set_sib(times_1, esp, base);
142     set_disp8(disp);
143   } else {
144     // [base + disp/r]
145     set_modrm(2, base);
146     if (base.is(esp)) set_sib(times_1, esp, base);
147     set_dispr(disp, rmode);
148   }
149 }
150 
151 
Operand(Register base,Register index,ScaleFactor scale,int32_t disp,RelocInfo::Mode rmode)152 Operand::Operand(Register base,
153                  Register index,
154                  ScaleFactor scale,
155                  int32_t disp,
156                  RelocInfo::Mode rmode) {
157   DCHECK(!index.is(esp));  // illegal addressing mode
158   // [base + index*scale + disp/r]
159   if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
160     // [base + index*scale]
161     set_modrm(0, esp);
162     set_sib(scale, index, base);
163   } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
164     // [base + index*scale + disp8]
165     set_modrm(1, esp);
166     set_sib(scale, index, base);
167     set_disp8(disp);
168   } else {
169     // [base + index*scale + disp/r]
170     set_modrm(2, esp);
171     set_sib(scale, index, base);
172     set_dispr(disp, rmode);
173   }
174 }
175 
176 
Operand(Register index,ScaleFactor scale,int32_t disp,RelocInfo::Mode rmode)177 Operand::Operand(Register index,
178                  ScaleFactor scale,
179                  int32_t disp,
180                  RelocInfo::Mode rmode) {
181   DCHECK(!index.is(esp));  // illegal addressing mode
182   // [index*scale + disp/r]
183   set_modrm(0, esp);
184   set_sib(scale, index, ebp);
185   set_dispr(disp, rmode);
186 }
187 
188 
is_reg(Register reg) const189 bool Operand::is_reg(Register reg) const {
190   return ((buf_[0] & 0xF8) == 0xC0)  // addressing mode is register only.
191       && ((buf_[0] & 0x07) == reg.code());  // register codes match.
192 }
193 
194 
is_reg_only() const195 bool Operand::is_reg_only() const {
196   return (buf_[0] & 0xF8) == 0xC0;  // Addressing mode is register only.
197 }
198 
199 
reg() const200 Register Operand::reg() const {
201   DCHECK(is_reg_only());
202   return Register::from_code(buf_[0] & 0x07);
203 }
204 
205 
206 // -----------------------------------------------------------------------------
207 // Implementation of Assembler.
208 
209 // Emit a single byte. Must always be inlined.
210 #define EMIT(x)                                 \
211   *pc_++ = (x)
212 
Assembler(Isolate * isolate,void * buffer,int buffer_size)213 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
214     : AssemblerBase(isolate, buffer, buffer_size) {
215 // Clear the buffer in debug mode unless it was provided by the
216 // caller in which case we can't be sure it's okay to overwrite
217 // existing code in it; see CodePatcher::CodePatcher(...).
218 #ifdef DEBUG
219   if (own_buffer_) {
220     memset(buffer_, 0xCC, buffer_size_);  // int3
221   }
222 #endif
223 
224   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
225 }
226 
227 
GetCode(CodeDesc * desc)228 void Assembler::GetCode(CodeDesc* desc) {
229   // Finalize code (at this point overflow() may be true, but the gap ensures
230   // that we are still not overlapping instructions and relocation info).
231   DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
232   // Set up code descriptor.
233   desc->buffer = buffer_;
234   desc->buffer_size = buffer_size_;
235   desc->instr_size = pc_offset();
236   desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
237   desc->origin = this;
238   desc->constant_pool_size = 0;
239   desc->unwinding_info_size = 0;
240   desc->unwinding_info = nullptr;
241 }
242 
243 
Align(int m)244 void Assembler::Align(int m) {
245   DCHECK(base::bits::IsPowerOfTwo32(m));
246   int mask = m - 1;
247   int addr = pc_offset();
248   Nop((m - (addr & mask)) & mask);
249 }
250 
251 
IsNop(Address addr)252 bool Assembler::IsNop(Address addr) {
253   Address a = addr;
254   while (*a == 0x66) a++;
255   if (*a == 0x90) return true;
256   if (a[0] == 0xf && a[1] == 0x1f) return true;
257   return false;
258 }
259 
260 
Nop(int bytes)261 void Assembler::Nop(int bytes) {
262   EnsureSpace ensure_space(this);
263 
264   // Older CPUs that do not support SSE2 may not support multibyte NOP
265   // instructions.
266   for (; bytes > 0; bytes--) {
267     EMIT(0x90);
268   }
269   return;
270 }
271 
272 
CodeTargetAlign()273 void Assembler::CodeTargetAlign() {
274   Align(16);  // Preferred alignment of jump targets on ia32.
275 }
276 
277 
cpuid()278 void Assembler::cpuid() {
279   EnsureSpace ensure_space(this);
280   EMIT(0x0F);
281   EMIT(0xA2);
282 }
283 
284 
pushad()285 void Assembler::pushad() {
286   EnsureSpace ensure_space(this);
287   EMIT(0x60);
288 }
289 
290 
popad()291 void Assembler::popad() {
292   EnsureSpace ensure_space(this);
293   EMIT(0x61);
294 }
295 
296 
pushfd()297 void Assembler::pushfd() {
298   EnsureSpace ensure_space(this);
299   EMIT(0x9C);
300 }
301 
302 
popfd()303 void Assembler::popfd() {
304   EnsureSpace ensure_space(this);
305   EMIT(0x9D);
306 }
307 
308 
push(const Immediate & x)309 void Assembler::push(const Immediate& x) {
310   EnsureSpace ensure_space(this);
311   if (x.is_int8()) {
312     EMIT(0x6a);
313     EMIT(x.x_);
314   } else {
315     EMIT(0x68);
316     emit(x);
317   }
318 }
319 
320 
push_imm32(int32_t imm32)321 void Assembler::push_imm32(int32_t imm32) {
322   EnsureSpace ensure_space(this);
323   EMIT(0x68);
324   emit(imm32);
325 }
326 
327 
push(Register src)328 void Assembler::push(Register src) {
329   EnsureSpace ensure_space(this);
330   EMIT(0x50 | src.code());
331 }
332 
333 
push(const Operand & src)334 void Assembler::push(const Operand& src) {
335   EnsureSpace ensure_space(this);
336   EMIT(0xFF);
337   emit_operand(esi, src);
338 }
339 
340 
pop(Register dst)341 void Assembler::pop(Register dst) {
342   DCHECK(reloc_info_writer.last_pc() != NULL);
343   EnsureSpace ensure_space(this);
344   EMIT(0x58 | dst.code());
345 }
346 
347 
pop(const Operand & dst)348 void Assembler::pop(const Operand& dst) {
349   EnsureSpace ensure_space(this);
350   EMIT(0x8F);
351   emit_operand(eax, dst);
352 }
353 
354 
enter(const Immediate & size)355 void Assembler::enter(const Immediate& size) {
356   EnsureSpace ensure_space(this);
357   EMIT(0xC8);
358   emit_w(size);
359   EMIT(0);
360 }
361 
362 
leave()363 void Assembler::leave() {
364   EnsureSpace ensure_space(this);
365   EMIT(0xC9);
366 }
367 
368 
mov_b(Register dst,const Operand & src)369 void Assembler::mov_b(Register dst, const Operand& src) {
370   CHECK(dst.is_byte_register());
371   EnsureSpace ensure_space(this);
372   EMIT(0x8A);
373   emit_operand(dst, src);
374 }
375 
376 
mov_b(const Operand & dst,const Immediate & src)377 void Assembler::mov_b(const Operand& dst, const Immediate& src) {
378   EnsureSpace ensure_space(this);
379   EMIT(0xC6);
380   emit_operand(eax, dst);
381   EMIT(static_cast<int8_t>(src.x_));
382 }
383 
384 
mov_b(const Operand & dst,int8_t imm8)385 void Assembler::mov_b(const Operand& dst, int8_t imm8) {
386   EnsureSpace ensure_space(this);
387   EMIT(0xC6);
388   emit_operand(eax, dst);
389   EMIT(imm8);
390 }
391 
392 
mov_b(const Operand & dst,Register src)393 void Assembler::mov_b(const Operand& dst, Register src) {
394   CHECK(src.is_byte_register());
395   EnsureSpace ensure_space(this);
396   EMIT(0x88);
397   emit_operand(src, dst);
398 }
399 
400 
mov_w(Register dst,const Operand & src)401 void Assembler::mov_w(Register dst, const Operand& src) {
402   EnsureSpace ensure_space(this);
403   EMIT(0x66);
404   EMIT(0x8B);
405   emit_operand(dst, src);
406 }
407 
408 
mov_w(const Operand & dst,Register src)409 void Assembler::mov_w(const Operand& dst, Register src) {
410   EnsureSpace ensure_space(this);
411   EMIT(0x66);
412   EMIT(0x89);
413   emit_operand(src, dst);
414 }
415 
416 
mov_w(const Operand & dst,int16_t imm16)417 void Assembler::mov_w(const Operand& dst, int16_t imm16) {
418   EnsureSpace ensure_space(this);
419   EMIT(0x66);
420   EMIT(0xC7);
421   emit_operand(eax, dst);
422   EMIT(static_cast<int8_t>(imm16 & 0xff));
423   EMIT(static_cast<int8_t>(imm16 >> 8));
424 }
425 
426 
mov_w(const Operand & dst,const Immediate & src)427 void Assembler::mov_w(const Operand& dst, const Immediate& src) {
428   EnsureSpace ensure_space(this);
429   EMIT(0x66);
430   EMIT(0xC7);
431   emit_operand(eax, dst);
432   EMIT(static_cast<int8_t>(src.x_ & 0xff));
433   EMIT(static_cast<int8_t>(src.x_ >> 8));
434 }
435 
436 
mov(Register dst,int32_t imm32)437 void Assembler::mov(Register dst, int32_t imm32) {
438   EnsureSpace ensure_space(this);
439   EMIT(0xB8 | dst.code());
440   emit(imm32);
441 }
442 
443 
mov(Register dst,const Immediate & x)444 void Assembler::mov(Register dst, const Immediate& x) {
445   EnsureSpace ensure_space(this);
446   EMIT(0xB8 | dst.code());
447   emit(x);
448 }
449 
450 
mov(Register dst,Handle<Object> handle)451 void Assembler::mov(Register dst, Handle<Object> handle) {
452   EnsureSpace ensure_space(this);
453   EMIT(0xB8 | dst.code());
454   emit(handle);
455 }
456 
457 
mov(Register dst,const Operand & src)458 void Assembler::mov(Register dst, const Operand& src) {
459   EnsureSpace ensure_space(this);
460   EMIT(0x8B);
461   emit_operand(dst, src);
462 }
463 
464 
mov(Register dst,Register src)465 void Assembler::mov(Register dst, Register src) {
466   EnsureSpace ensure_space(this);
467   EMIT(0x89);
468   EMIT(0xC0 | src.code() << 3 | dst.code());
469 }
470 
471 
mov(const Operand & dst,const Immediate & x)472 void Assembler::mov(const Operand& dst, const Immediate& x) {
473   EnsureSpace ensure_space(this);
474   EMIT(0xC7);
475   emit_operand(eax, dst);
476   emit(x);
477 }
478 
479 
mov(const Operand & dst,Handle<Object> handle)480 void Assembler::mov(const Operand& dst, Handle<Object> handle) {
481   EnsureSpace ensure_space(this);
482   EMIT(0xC7);
483   emit_operand(eax, dst);
484   emit(handle);
485 }
486 
487 
mov(const Operand & dst,Register src)488 void Assembler::mov(const Operand& dst, Register src) {
489   EnsureSpace ensure_space(this);
490   EMIT(0x89);
491   emit_operand(src, dst);
492 }
493 
494 
movsx_b(Register dst,const Operand & src)495 void Assembler::movsx_b(Register dst, const Operand& src) {
496   EnsureSpace ensure_space(this);
497   EMIT(0x0F);
498   EMIT(0xBE);
499   emit_operand(dst, src);
500 }
501 
502 
movsx_w(Register dst,const Operand & src)503 void Assembler::movsx_w(Register dst, const Operand& src) {
504   EnsureSpace ensure_space(this);
505   EMIT(0x0F);
506   EMIT(0xBF);
507   emit_operand(dst, src);
508 }
509 
510 
movzx_b(Register dst,const Operand & src)511 void Assembler::movzx_b(Register dst, const Operand& src) {
512   EnsureSpace ensure_space(this);
513   EMIT(0x0F);
514   EMIT(0xB6);
515   emit_operand(dst, src);
516 }
517 
518 
movzx_w(Register dst,const Operand & src)519 void Assembler::movzx_w(Register dst, const Operand& src) {
520   EnsureSpace ensure_space(this);
521   EMIT(0x0F);
522   EMIT(0xB7);
523   emit_operand(dst, src);
524 }
525 
526 
cld()527 void Assembler::cld() {
528   EnsureSpace ensure_space(this);
529   EMIT(0xFC);
530 }
531 
532 
rep_movs()533 void Assembler::rep_movs() {
534   EnsureSpace ensure_space(this);
535   EMIT(0xF3);
536   EMIT(0xA5);
537 }
538 
539 
rep_stos()540 void Assembler::rep_stos() {
541   EnsureSpace ensure_space(this);
542   EMIT(0xF3);
543   EMIT(0xAB);
544 }
545 
546 
stos()547 void Assembler::stos() {
548   EnsureSpace ensure_space(this);
549   EMIT(0xAB);
550 }
551 
552 
xchg(Register dst,Register src)553 void Assembler::xchg(Register dst, Register src) {
554   EnsureSpace ensure_space(this);
555   if (src.is(eax) || dst.is(eax)) {  // Single-byte encoding.
556     EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
557   } else {
558     EMIT(0x87);
559     EMIT(0xC0 | src.code() << 3 | dst.code());
560   }
561 }
562 
563 
xchg(Register dst,const Operand & src)564 void Assembler::xchg(Register dst, const Operand& src) {
565   EnsureSpace ensure_space(this);
566   EMIT(0x87);
567   emit_operand(dst, src);
568 }
569 
xchg_b(Register reg,const Operand & op)570 void Assembler::xchg_b(Register reg, const Operand& op) {
571   EnsureSpace ensure_space(this);
572   EMIT(0x86);
573   emit_operand(reg, op);
574 }
575 
xchg_w(Register reg,const Operand & op)576 void Assembler::xchg_w(Register reg, const Operand& op) {
577   EnsureSpace ensure_space(this);
578   EMIT(0x66);
579   EMIT(0x87);
580   emit_operand(reg, op);
581 }
582 
lock()583 void Assembler::lock() {
584   EnsureSpace ensure_space(this);
585   EMIT(0xF0);
586 }
587 
cmpxchg(const Operand & dst,Register src)588 void Assembler::cmpxchg(const Operand& dst, Register src) {
589   EnsureSpace ensure_space(this);
590   EMIT(0x0F);
591   EMIT(0xB1);
592   emit_operand(src, dst);
593 }
594 
cmpxchg_b(const Operand & dst,Register src)595 void Assembler::cmpxchg_b(const Operand& dst, Register src) {
596   EnsureSpace ensure_space(this);
597   EMIT(0x0F);
598   EMIT(0xB0);
599   emit_operand(src, dst);
600 }
601 
cmpxchg_w(const Operand & dst,Register src)602 void Assembler::cmpxchg_w(const Operand& dst, Register src) {
603   EnsureSpace ensure_space(this);
604   EMIT(0x66);
605   EMIT(0x0F);
606   EMIT(0xB1);
607   emit_operand(src, dst);
608 }
609 
adc(Register dst,int32_t imm32)610 void Assembler::adc(Register dst, int32_t imm32) {
611   EnsureSpace ensure_space(this);
612   emit_arith(2, Operand(dst), Immediate(imm32));
613 }
614 
615 
adc(Register dst,const Operand & src)616 void Assembler::adc(Register dst, const Operand& src) {
617   EnsureSpace ensure_space(this);
618   EMIT(0x13);
619   emit_operand(dst, src);
620 }
621 
622 
add(Register dst,const Operand & src)623 void Assembler::add(Register dst, const Operand& src) {
624   EnsureSpace ensure_space(this);
625   EMIT(0x03);
626   emit_operand(dst, src);
627 }
628 
629 
add(const Operand & dst,Register src)630 void Assembler::add(const Operand& dst, Register src) {
631   EnsureSpace ensure_space(this);
632   EMIT(0x01);
633   emit_operand(src, dst);
634 }
635 
636 
add(const Operand & dst,const Immediate & x)637 void Assembler::add(const Operand& dst, const Immediate& x) {
638   DCHECK(reloc_info_writer.last_pc() != NULL);
639   EnsureSpace ensure_space(this);
640   emit_arith(0, dst, x);
641 }
642 
643 
and_(Register dst,int32_t imm32)644 void Assembler::and_(Register dst, int32_t imm32) {
645   and_(dst, Immediate(imm32));
646 }
647 
648 
and_(Register dst,const Immediate & x)649 void Assembler::and_(Register dst, const Immediate& x) {
650   EnsureSpace ensure_space(this);
651   emit_arith(4, Operand(dst), x);
652 }
653 
654 
and_(Register dst,const Operand & src)655 void Assembler::and_(Register dst, const Operand& src) {
656   EnsureSpace ensure_space(this);
657   EMIT(0x23);
658   emit_operand(dst, src);
659 }
660 
661 
and_(const Operand & dst,const Immediate & x)662 void Assembler::and_(const Operand& dst, const Immediate& x) {
663   EnsureSpace ensure_space(this);
664   emit_arith(4, dst, x);
665 }
666 
667 
and_(const Operand & dst,Register src)668 void Assembler::and_(const Operand& dst, Register src) {
669   EnsureSpace ensure_space(this);
670   EMIT(0x21);
671   emit_operand(src, dst);
672 }
673 
cmpb(const Operand & op,Immediate imm8)674 void Assembler::cmpb(const Operand& op, Immediate imm8) {
675   DCHECK(imm8.is_int8() || imm8.is_uint8());
676   EnsureSpace ensure_space(this);
677   if (op.is_reg(eax)) {
678     EMIT(0x3C);
679   } else {
680     EMIT(0x80);
681     emit_operand(edi, op);  // edi == 7
682   }
683   emit_b(imm8);
684 }
685 
686 
cmpb(const Operand & op,Register reg)687 void Assembler::cmpb(const Operand& op, Register reg) {
688   CHECK(reg.is_byte_register());
689   EnsureSpace ensure_space(this);
690   EMIT(0x38);
691   emit_operand(reg, op);
692 }
693 
694 
cmpb(Register reg,const Operand & op)695 void Assembler::cmpb(Register reg, const Operand& op) {
696   CHECK(reg.is_byte_register());
697   EnsureSpace ensure_space(this);
698   EMIT(0x3A);
699   emit_operand(reg, op);
700 }
701 
702 
cmpw(const Operand & op,Immediate imm16)703 void Assembler::cmpw(const Operand& op, Immediate imm16) {
704   DCHECK(imm16.is_int16());
705   EnsureSpace ensure_space(this);
706   EMIT(0x66);
707   EMIT(0x81);
708   emit_operand(edi, op);
709   emit_w(imm16);
710 }
711 
cmpw(Register reg,const Operand & op)712 void Assembler::cmpw(Register reg, const Operand& op) {
713   EnsureSpace ensure_space(this);
714   EMIT(0x66);
715   EMIT(0x3B);
716   emit_operand(reg, op);
717 }
718 
cmpw(const Operand & op,Register reg)719 void Assembler::cmpw(const Operand& op, Register reg) {
720   EnsureSpace ensure_space(this);
721   EMIT(0x66);
722   EMIT(0x39);
723   emit_operand(reg, op);
724 }
725 
cmp(Register reg,int32_t imm32)726 void Assembler::cmp(Register reg, int32_t imm32) {
727   EnsureSpace ensure_space(this);
728   emit_arith(7, Operand(reg), Immediate(imm32));
729 }
730 
731 
cmp(Register reg,Handle<Object> handle)732 void Assembler::cmp(Register reg, Handle<Object> handle) {
733   EnsureSpace ensure_space(this);
734   emit_arith(7, Operand(reg), Immediate(handle));
735 }
736 
737 
cmp(Register reg,const Operand & op)738 void Assembler::cmp(Register reg, const Operand& op) {
739   EnsureSpace ensure_space(this);
740   EMIT(0x3B);
741   emit_operand(reg, op);
742 }
743 
cmp(const Operand & op,Register reg)744 void Assembler::cmp(const Operand& op, Register reg) {
745   EnsureSpace ensure_space(this);
746   EMIT(0x39);
747   emit_operand(reg, op);
748 }
749 
cmp(const Operand & op,const Immediate & imm)750 void Assembler::cmp(const Operand& op, const Immediate& imm) {
751   EnsureSpace ensure_space(this);
752   emit_arith(7, op, imm);
753 }
754 
755 
cmp(const Operand & op,Handle<Object> handle)756 void Assembler::cmp(const Operand& op, Handle<Object> handle) {
757   EnsureSpace ensure_space(this);
758   emit_arith(7, op, Immediate(handle));
759 }
760 
761 
cmpb_al(const Operand & op)762 void Assembler::cmpb_al(const Operand& op) {
763   EnsureSpace ensure_space(this);
764   EMIT(0x38);  // CMP r/m8, r8
765   emit_operand(eax, op);  // eax has same code as register al.
766 }
767 
768 
cmpw_ax(const Operand & op)769 void Assembler::cmpw_ax(const Operand& op) {
770   EnsureSpace ensure_space(this);
771   EMIT(0x66);
772   EMIT(0x39);  // CMP r/m16, r16
773   emit_operand(eax, op);  // eax has same code as register ax.
774 }
775 
776 
dec_b(Register dst)777 void Assembler::dec_b(Register dst) {
778   CHECK(dst.is_byte_register());
779   EnsureSpace ensure_space(this);
780   EMIT(0xFE);
781   EMIT(0xC8 | dst.code());
782 }
783 
784 
dec_b(const Operand & dst)785 void Assembler::dec_b(const Operand& dst) {
786   EnsureSpace ensure_space(this);
787   EMIT(0xFE);
788   emit_operand(ecx, dst);
789 }
790 
791 
dec(Register dst)792 void Assembler::dec(Register dst) {
793   EnsureSpace ensure_space(this);
794   EMIT(0x48 | dst.code());
795 }
796 
797 
dec(const Operand & dst)798 void Assembler::dec(const Operand& dst) {
799   EnsureSpace ensure_space(this);
800   EMIT(0xFF);
801   emit_operand(ecx, dst);
802 }
803 
804 
cdq()805 void Assembler::cdq() {
806   EnsureSpace ensure_space(this);
807   EMIT(0x99);
808 }
809 
810 
idiv(const Operand & src)811 void Assembler::idiv(const Operand& src) {
812   EnsureSpace ensure_space(this);
813   EMIT(0xF7);
814   emit_operand(edi, src);
815 }
816 
817 
div(const Operand & src)818 void Assembler::div(const Operand& src) {
819   EnsureSpace ensure_space(this);
820   EMIT(0xF7);
821   emit_operand(esi, src);
822 }
823 
824 
imul(Register reg)825 void Assembler::imul(Register reg) {
826   EnsureSpace ensure_space(this);
827   EMIT(0xF7);
828   EMIT(0xE8 | reg.code());
829 }
830 
831 
imul(Register dst,const Operand & src)832 void Assembler::imul(Register dst, const Operand& src) {
833   EnsureSpace ensure_space(this);
834   EMIT(0x0F);
835   EMIT(0xAF);
836   emit_operand(dst, src);
837 }
838 
839 
imul(Register dst,Register src,int32_t imm32)840 void Assembler::imul(Register dst, Register src, int32_t imm32) {
841   imul(dst, Operand(src), imm32);
842 }
843 
844 
imul(Register dst,const Operand & src,int32_t imm32)845 void Assembler::imul(Register dst, const Operand& src, int32_t imm32) {
846   EnsureSpace ensure_space(this);
847   if (is_int8(imm32)) {
848     EMIT(0x6B);
849     emit_operand(dst, src);
850     EMIT(imm32);
851   } else {
852     EMIT(0x69);
853     emit_operand(dst, src);
854     emit(imm32);
855   }
856 }
857 
858 
inc(Register dst)859 void Assembler::inc(Register dst) {
860   EnsureSpace ensure_space(this);
861   EMIT(0x40 | dst.code());
862 }
863 
864 
inc(const Operand & dst)865 void Assembler::inc(const Operand& dst) {
866   EnsureSpace ensure_space(this);
867   EMIT(0xFF);
868   emit_operand(eax, dst);
869 }
870 
871 
lea(Register dst,const Operand & src)872 void Assembler::lea(Register dst, const Operand& src) {
873   EnsureSpace ensure_space(this);
874   EMIT(0x8D);
875   emit_operand(dst, src);
876 }
877 
878 
mul(Register src)879 void Assembler::mul(Register src) {
880   EnsureSpace ensure_space(this);
881   EMIT(0xF7);
882   EMIT(0xE0 | src.code());
883 }
884 
885 
neg(Register dst)886 void Assembler::neg(Register dst) {
887   EnsureSpace ensure_space(this);
888   EMIT(0xF7);
889   EMIT(0xD8 | dst.code());
890 }
891 
892 
neg(const Operand & dst)893 void Assembler::neg(const Operand& dst) {
894   EnsureSpace ensure_space(this);
895   EMIT(0xF7);
896   emit_operand(ebx, dst);
897 }
898 
899 
not_(Register dst)900 void Assembler::not_(Register dst) {
901   EnsureSpace ensure_space(this);
902   EMIT(0xF7);
903   EMIT(0xD0 | dst.code());
904 }
905 
906 
not_(const Operand & dst)907 void Assembler::not_(const Operand& dst) {
908   EnsureSpace ensure_space(this);
909   EMIT(0xF7);
910   emit_operand(edx, dst);
911 }
912 
913 
or_(Register dst,int32_t imm32)914 void Assembler::or_(Register dst, int32_t imm32) {
915   EnsureSpace ensure_space(this);
916   emit_arith(1, Operand(dst), Immediate(imm32));
917 }
918 
919 
or_(Register dst,const Operand & src)920 void Assembler::or_(Register dst, const Operand& src) {
921   EnsureSpace ensure_space(this);
922   EMIT(0x0B);
923   emit_operand(dst, src);
924 }
925 
926 
or_(const Operand & dst,const Immediate & x)927 void Assembler::or_(const Operand& dst, const Immediate& x) {
928   EnsureSpace ensure_space(this);
929   emit_arith(1, dst, x);
930 }
931 
932 
or_(const Operand & dst,Register src)933 void Assembler::or_(const Operand& dst, Register src) {
934   EnsureSpace ensure_space(this);
935   EMIT(0x09);
936   emit_operand(src, dst);
937 }
938 
939 
rcl(Register dst,uint8_t imm8)940 void Assembler::rcl(Register dst, uint8_t imm8) {
941   EnsureSpace ensure_space(this);
942   DCHECK(is_uint5(imm8));  // illegal shift count
943   if (imm8 == 1) {
944     EMIT(0xD1);
945     EMIT(0xD0 | dst.code());
946   } else {
947     EMIT(0xC1);
948     EMIT(0xD0 | dst.code());
949     EMIT(imm8);
950   }
951 }
952 
953 
rcr(Register dst,uint8_t imm8)954 void Assembler::rcr(Register dst, uint8_t imm8) {
955   EnsureSpace ensure_space(this);
956   DCHECK(is_uint5(imm8));  // illegal shift count
957   if (imm8 == 1) {
958     EMIT(0xD1);
959     EMIT(0xD8 | dst.code());
960   } else {
961     EMIT(0xC1);
962     EMIT(0xD8 | dst.code());
963     EMIT(imm8);
964   }
965 }
966 
967 
ror(const Operand & dst,uint8_t imm8)968 void Assembler::ror(const Operand& dst, uint8_t imm8) {
969   EnsureSpace ensure_space(this);
970   DCHECK(is_uint5(imm8));  // illegal shift count
971   if (imm8 == 1) {
972     EMIT(0xD1);
973     emit_operand(ecx, dst);
974   } else {
975     EMIT(0xC1);
976     emit_operand(ecx, dst);
977     EMIT(imm8);
978   }
979 }
980 
981 
ror_cl(const Operand & dst)982 void Assembler::ror_cl(const Operand& dst) {
983   EnsureSpace ensure_space(this);
984   EMIT(0xD3);
985   emit_operand(ecx, dst);
986 }
987 
988 
sar(const Operand & dst,uint8_t imm8)989 void Assembler::sar(const Operand& dst, uint8_t imm8) {
990   EnsureSpace ensure_space(this);
991   DCHECK(is_uint5(imm8));  // illegal shift count
992   if (imm8 == 1) {
993     EMIT(0xD1);
994     emit_operand(edi, dst);
995   } else {
996     EMIT(0xC1);
997     emit_operand(edi, dst);
998     EMIT(imm8);
999   }
1000 }
1001 
1002 
sar_cl(const Operand & dst)1003 void Assembler::sar_cl(const Operand& dst) {
1004   EnsureSpace ensure_space(this);
1005   EMIT(0xD3);
1006   emit_operand(edi, dst);
1007 }
1008 
sbb(Register dst,const Operand & src)1009 void Assembler::sbb(Register dst, const Operand& src) {
1010   EnsureSpace ensure_space(this);
1011   EMIT(0x1B);
1012   emit_operand(dst, src);
1013 }
1014 
shld(Register dst,Register src,uint8_t shift)1015 void Assembler::shld(Register dst, Register src, uint8_t shift) {
1016   DCHECK(is_uint5(shift));
1017   EnsureSpace ensure_space(this);
1018   EMIT(0x0F);
1019   EMIT(0xA4);
1020   emit_operand(src, Operand(dst));
1021   EMIT(shift);
1022 }
1023 
shld_cl(Register dst,Register src)1024 void Assembler::shld_cl(Register dst, Register src) {
1025   EnsureSpace ensure_space(this);
1026   EMIT(0x0F);
1027   EMIT(0xA5);
1028   emit_operand(src, Operand(dst));
1029 }
1030 
1031 
shl(const Operand & dst,uint8_t imm8)1032 void Assembler::shl(const Operand& dst, uint8_t imm8) {
1033   EnsureSpace ensure_space(this);
1034   DCHECK(is_uint5(imm8));  // illegal shift count
1035   if (imm8 == 1) {
1036     EMIT(0xD1);
1037     emit_operand(esp, dst);
1038   } else {
1039     EMIT(0xC1);
1040     emit_operand(esp, dst);
1041     EMIT(imm8);
1042   }
1043 }
1044 
1045 
shl_cl(const Operand & dst)1046 void Assembler::shl_cl(const Operand& dst) {
1047   EnsureSpace ensure_space(this);
1048   EMIT(0xD3);
1049   emit_operand(esp, dst);
1050 }
1051 
shr(const Operand & dst,uint8_t imm8)1052 void Assembler::shr(const Operand& dst, uint8_t imm8) {
1053   EnsureSpace ensure_space(this);
1054   DCHECK(is_uint5(imm8));  // illegal shift count
1055   if (imm8 == 1) {
1056     EMIT(0xD1);
1057     emit_operand(ebp, dst);
1058   } else {
1059     EMIT(0xC1);
1060     emit_operand(ebp, dst);
1061     EMIT(imm8);
1062   }
1063 }
1064 
1065 
shr_cl(const Operand & dst)1066 void Assembler::shr_cl(const Operand& dst) {
1067   EnsureSpace ensure_space(this);
1068   EMIT(0xD3);
1069   emit_operand(ebp, dst);
1070 }
1071 
shrd(Register dst,Register src,uint8_t shift)1072 void Assembler::shrd(Register dst, Register src, uint8_t shift) {
1073   DCHECK(is_uint5(shift));
1074   EnsureSpace ensure_space(this);
1075   EMIT(0x0F);
1076   EMIT(0xAC);
1077   emit_operand(dst, Operand(src));
1078   EMIT(shift);
1079 }
1080 
shrd_cl(const Operand & dst,Register src)1081 void Assembler::shrd_cl(const Operand& dst, Register src) {
1082   EnsureSpace ensure_space(this);
1083   EMIT(0x0F);
1084   EMIT(0xAD);
1085   emit_operand(src, dst);
1086 }
1087 
sub(const Operand & dst,const Immediate & x)1088 void Assembler::sub(const Operand& dst, const Immediate& x) {
1089   EnsureSpace ensure_space(this);
1090   emit_arith(5, dst, x);
1091 }
1092 
1093 
sub(Register dst,const Operand & src)1094 void Assembler::sub(Register dst, const Operand& src) {
1095   EnsureSpace ensure_space(this);
1096   EMIT(0x2B);
1097   emit_operand(dst, src);
1098 }
1099 
1100 
sub(const Operand & dst,Register src)1101 void Assembler::sub(const Operand& dst, Register src) {
1102   EnsureSpace ensure_space(this);
1103   EMIT(0x29);
1104   emit_operand(src, dst);
1105 }
1106 
1107 
test(Register reg,const Immediate & imm)1108 void Assembler::test(Register reg, const Immediate& imm) {
1109   if (imm.is_uint8()) {
1110     test_b(reg, imm);
1111     return;
1112   }
1113 
1114   EnsureSpace ensure_space(this);
1115   // This is not using emit_arith because test doesn't support
1116   // sign-extension of 8-bit operands.
1117   if (reg.is(eax)) {
1118     EMIT(0xA9);
1119   } else {
1120     EMIT(0xF7);
1121     EMIT(0xC0 | reg.code());
1122   }
1123   emit(imm);
1124 }
1125 
1126 
test(Register reg,const Operand & op)1127 void Assembler::test(Register reg, const Operand& op) {
1128   EnsureSpace ensure_space(this);
1129   EMIT(0x85);
1130   emit_operand(reg, op);
1131 }
1132 
1133 
test_b(Register reg,const Operand & op)1134 void Assembler::test_b(Register reg, const Operand& op) {
1135   CHECK(reg.is_byte_register());
1136   EnsureSpace ensure_space(this);
1137   EMIT(0x84);
1138   emit_operand(reg, op);
1139 }
1140 
1141 
test(const Operand & op,const Immediate & imm)1142 void Assembler::test(const Operand& op, const Immediate& imm) {
1143   if (op.is_reg_only()) {
1144     test(op.reg(), imm);
1145     return;
1146   }
1147   if (imm.is_uint8()) {
1148     return test_b(op, imm);
1149   }
1150   EnsureSpace ensure_space(this);
1151   EMIT(0xF7);
1152   emit_operand(eax, op);
1153   emit(imm);
1154 }
1155 
test_b(Register reg,Immediate imm8)1156 void Assembler::test_b(Register reg, Immediate imm8) {
1157   DCHECK(imm8.is_uint8());
1158   EnsureSpace ensure_space(this);
1159   // Only use test against byte for registers that have a byte
1160   // variant: eax, ebx, ecx, and edx.
1161   if (reg.is(eax)) {
1162     EMIT(0xA8);
1163     emit_b(imm8);
1164   } else if (reg.is_byte_register()) {
1165     emit_arith_b(0xF6, 0xC0, reg, static_cast<uint8_t>(imm8.x_));
1166   } else {
1167     EMIT(0x66);
1168     EMIT(0xF7);
1169     EMIT(0xC0 | reg.code());
1170     emit_w(imm8);
1171   }
1172 }
1173 
test_b(const Operand & op,Immediate imm8)1174 void Assembler::test_b(const Operand& op, Immediate imm8) {
1175   if (op.is_reg_only()) {
1176     test_b(op.reg(), imm8);
1177     return;
1178   }
1179   EnsureSpace ensure_space(this);
1180   EMIT(0xF6);
1181   emit_operand(eax, op);
1182   emit_b(imm8);
1183 }
1184 
test_w(Register reg,Immediate imm16)1185 void Assembler::test_w(Register reg, Immediate imm16) {
1186   DCHECK(imm16.is_int16() || imm16.is_uint16());
1187   EnsureSpace ensure_space(this);
1188   if (reg.is(eax)) {
1189     EMIT(0xA9);
1190     emit_w(imm16);
1191   } else {
1192     EMIT(0x66);
1193     EMIT(0xF7);
1194     EMIT(0xc0 | reg.code());
1195     emit_w(imm16);
1196   }
1197 }
1198 
test_w(Register reg,const Operand & op)1199 void Assembler::test_w(Register reg, const Operand& op) {
1200   EnsureSpace ensure_space(this);
1201   EMIT(0x66);
1202   EMIT(0x85);
1203   emit_operand(reg, op);
1204 }
1205 
test_w(const Operand & op,Immediate imm16)1206 void Assembler::test_w(const Operand& op, Immediate imm16) {
1207   DCHECK(imm16.is_int16() || imm16.is_uint16());
1208   if (op.is_reg_only()) {
1209     test_w(op.reg(), imm16);
1210     return;
1211   }
1212   EnsureSpace ensure_space(this);
1213   EMIT(0x66);
1214   EMIT(0xF7);
1215   emit_operand(eax, op);
1216   emit_w(imm16);
1217 }
1218 
xor_(Register dst,int32_t imm32)1219 void Assembler::xor_(Register dst, int32_t imm32) {
1220   EnsureSpace ensure_space(this);
1221   emit_arith(6, Operand(dst), Immediate(imm32));
1222 }
1223 
1224 
xor_(Register dst,const Operand & src)1225 void Assembler::xor_(Register dst, const Operand& src) {
1226   EnsureSpace ensure_space(this);
1227   EMIT(0x33);
1228   emit_operand(dst, src);
1229 }
1230 
1231 
xor_(const Operand & dst,Register src)1232 void Assembler::xor_(const Operand& dst, Register src) {
1233   EnsureSpace ensure_space(this);
1234   EMIT(0x31);
1235   emit_operand(src, dst);
1236 }
1237 
1238 
xor_(const Operand & dst,const Immediate & x)1239 void Assembler::xor_(const Operand& dst, const Immediate& x) {
1240   EnsureSpace ensure_space(this);
1241   emit_arith(6, dst, x);
1242 }
1243 
1244 
bt(const Operand & dst,Register src)1245 void Assembler::bt(const Operand& dst, Register src) {
1246   EnsureSpace ensure_space(this);
1247   EMIT(0x0F);
1248   EMIT(0xA3);
1249   emit_operand(src, dst);
1250 }
1251 
1252 
bts(const Operand & dst,Register src)1253 void Assembler::bts(const Operand& dst, Register src) {
1254   EnsureSpace ensure_space(this);
1255   EMIT(0x0F);
1256   EMIT(0xAB);
1257   emit_operand(src, dst);
1258 }
1259 
1260 
bsr(Register dst,const Operand & src)1261 void Assembler::bsr(Register dst, const Operand& src) {
1262   EnsureSpace ensure_space(this);
1263   EMIT(0x0F);
1264   EMIT(0xBD);
1265   emit_operand(dst, src);
1266 }
1267 
1268 
bsf(Register dst,const Operand & src)1269 void Assembler::bsf(Register dst, const Operand& src) {
1270   EnsureSpace ensure_space(this);
1271   EMIT(0x0F);
1272   EMIT(0xBC);
1273   emit_operand(dst, src);
1274 }
1275 
1276 
hlt()1277 void Assembler::hlt() {
1278   EnsureSpace ensure_space(this);
1279   EMIT(0xF4);
1280 }
1281 
1282 
int3()1283 void Assembler::int3() {
1284   EnsureSpace ensure_space(this);
1285   EMIT(0xCC);
1286 }
1287 
1288 
nop()1289 void Assembler::nop() {
1290   EnsureSpace ensure_space(this);
1291   EMIT(0x90);
1292 }
1293 
1294 
ret(int imm16)1295 void Assembler::ret(int imm16) {
1296   EnsureSpace ensure_space(this);
1297   DCHECK(is_uint16(imm16));
1298   if (imm16 == 0) {
1299     EMIT(0xC3);
1300   } else {
1301     EMIT(0xC2);
1302     EMIT(imm16 & 0xFF);
1303     EMIT((imm16 >> 8) & 0xFF);
1304   }
1305 }
1306 
1307 
ud2()1308 void Assembler::ud2() {
1309   EnsureSpace ensure_space(this);
1310   EMIT(0x0F);
1311   EMIT(0x0B);
1312 }
1313 
1314 
1315 // Labels refer to positions in the (to be) generated code.
1316 // There are bound, linked, and unused labels.
1317 //
1318 // Bound labels refer to known positions in the already
1319 // generated code. pos() is the position the label refers to.
1320 //
1321 // Linked labels refer to unknown positions in the code
1322 // to be generated; pos() is the position of the 32bit
1323 // Displacement of the last instruction using the label.
1324 
1325 
print(Label * L)1326 void Assembler::print(Label* L) {
1327   if (L->is_unused()) {
1328     PrintF("unused label\n");
1329   } else if (L->is_bound()) {
1330     PrintF("bound label to %d\n", L->pos());
1331   } else if (L->is_linked()) {
1332     Label l = *L;
1333     PrintF("unbound label");
1334     while (l.is_linked()) {
1335       Displacement disp = disp_at(&l);
1336       PrintF("@ %d ", l.pos());
1337       disp.print();
1338       PrintF("\n");
1339       disp.next(&l);
1340     }
1341   } else {
1342     PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1343   }
1344 }
1345 
1346 
bind_to(Label * L,int pos)1347 void Assembler::bind_to(Label* L, int pos) {
1348   EnsureSpace ensure_space(this);
1349   DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
1350   while (L->is_linked()) {
1351     Displacement disp = disp_at(L);
1352     int fixup_pos = L->pos();
1353     if (disp.type() == Displacement::CODE_ABSOLUTE) {
1354       long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos));
1355       internal_reference_positions_.push_back(fixup_pos);
1356     } else if (disp.type() == Displacement::CODE_RELATIVE) {
1357       // Relative to Code* heap object pointer.
1358       long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1359     } else {
1360       if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1361         DCHECK(byte_at(fixup_pos - 1) == 0xE9);  // jmp expected
1362       }
1363       // Relative address, relative to point after address.
1364       int imm32 = pos - (fixup_pos + sizeof(int32_t));
1365       long_at_put(fixup_pos, imm32);
1366     }
1367     disp.next(L);
1368   }
1369   while (L->is_near_linked()) {
1370     int fixup_pos = L->near_link_pos();
1371     int offset_to_next =
1372         static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
1373     DCHECK(offset_to_next <= 0);
1374     // Relative address, relative to point after address.
1375     int disp = pos - fixup_pos - sizeof(int8_t);
1376     CHECK(0 <= disp && disp <= 127);
1377     set_byte_at(fixup_pos, disp);
1378     if (offset_to_next < 0) {
1379       L->link_to(fixup_pos + offset_to_next, Label::kNear);
1380     } else {
1381       L->UnuseNear();
1382     }
1383   }
1384   L->bind_to(pos);
1385 }
1386 
1387 
bind(Label * L)1388 void Assembler::bind(Label* L) {
1389   EnsureSpace ensure_space(this);
1390   DCHECK(!L->is_bound());  // label can only be bound once
1391   bind_to(L, pc_offset());
1392 }
1393 
1394 
call(Label * L)1395 void Assembler::call(Label* L) {
1396   EnsureSpace ensure_space(this);
1397   if (L->is_bound()) {
1398     const int long_size = 5;
1399     int offs = L->pos() - pc_offset();
1400     DCHECK(offs <= 0);
1401     // 1110 1000 #32-bit disp.
1402     EMIT(0xE8);
1403     emit(offs - long_size);
1404   } else {
1405     // 1110 1000 #32-bit disp.
1406     EMIT(0xE8);
1407     emit_disp(L, Displacement::OTHER);
1408   }
1409 }
1410 
1411 
call(byte * entry,RelocInfo::Mode rmode)1412 void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
1413   EnsureSpace ensure_space(this);
1414   DCHECK(!RelocInfo::IsCodeTarget(rmode));
1415   EMIT(0xE8);
1416   if (RelocInfo::IsRuntimeEntry(rmode)) {
1417     emit(reinterpret_cast<uint32_t>(entry), rmode);
1418   } else {
1419     emit(entry - (pc_ + sizeof(int32_t)), rmode);
1420   }
1421 }
1422 
1423 
CallSize(const Operand & adr)1424 int Assembler::CallSize(const Operand& adr) {
1425   // Call size is 1 (opcode) + adr.len_ (operand).
1426   return 1 + adr.len_;
1427 }
1428 
1429 
call(const Operand & adr)1430 void Assembler::call(const Operand& adr) {
1431   EnsureSpace ensure_space(this);
1432   EMIT(0xFF);
1433   emit_operand(edx, adr);
1434 }
1435 
1436 
CallSize(Handle<Code> code,RelocInfo::Mode rmode)1437 int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1438   return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
1439 }
1440 
1441 
call(Handle<Code> code,RelocInfo::Mode rmode,TypeFeedbackId ast_id)1442 void Assembler::call(Handle<Code> code,
1443                      RelocInfo::Mode rmode,
1444                      TypeFeedbackId ast_id) {
1445   EnsureSpace ensure_space(this);
1446   DCHECK(RelocInfo::IsCodeTarget(rmode)
1447       || rmode == RelocInfo::CODE_AGE_SEQUENCE);
1448   EMIT(0xE8);
1449   emit(code, rmode, ast_id);
1450 }
1451 
1452 
jmp(Label * L,Label::Distance distance)1453 void Assembler::jmp(Label* L, Label::Distance distance) {
1454   EnsureSpace ensure_space(this);
1455   if (L->is_bound()) {
1456     const int short_size = 2;
1457     const int long_size  = 5;
1458     int offs = L->pos() - pc_offset();
1459     DCHECK(offs <= 0);
1460     if (is_int8(offs - short_size)) {
1461       // 1110 1011 #8-bit disp.
1462       EMIT(0xEB);
1463       EMIT((offs - short_size) & 0xFF);
1464     } else {
1465       // 1110 1001 #32-bit disp.
1466       EMIT(0xE9);
1467       emit(offs - long_size);
1468     }
1469   } else if (distance == Label::kNear) {
1470     EMIT(0xEB);
1471     emit_near_disp(L);
1472   } else {
1473     // 1110 1001 #32-bit disp.
1474     EMIT(0xE9);
1475     emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1476   }
1477 }
1478 
1479 
jmp(byte * entry,RelocInfo::Mode rmode)1480 void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
1481   EnsureSpace ensure_space(this);
1482   DCHECK(!RelocInfo::IsCodeTarget(rmode));
1483   EMIT(0xE9);
1484   if (RelocInfo::IsRuntimeEntry(rmode)) {
1485     emit(reinterpret_cast<uint32_t>(entry), rmode);
1486   } else {
1487     emit(entry - (pc_ + sizeof(int32_t)), rmode);
1488   }
1489 }
1490 
1491 
jmp(const Operand & adr)1492 void Assembler::jmp(const Operand& adr) {
1493   EnsureSpace ensure_space(this);
1494   EMIT(0xFF);
1495   emit_operand(esp, adr);
1496 }
1497 
1498 
jmp(Handle<Code> code,RelocInfo::Mode rmode)1499 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1500   EnsureSpace ensure_space(this);
1501   DCHECK(RelocInfo::IsCodeTarget(rmode));
1502   EMIT(0xE9);
1503   emit(code, rmode);
1504 }
1505 
1506 
j(Condition cc,Label * L,Label::Distance distance)1507 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1508   EnsureSpace ensure_space(this);
1509   DCHECK(0 <= cc && static_cast<int>(cc) < 16);
1510   if (L->is_bound()) {
1511     const int short_size = 2;
1512     const int long_size  = 6;
1513     int offs = L->pos() - pc_offset();
1514     DCHECK(offs <= 0);
1515     if (is_int8(offs - short_size)) {
1516       // 0111 tttn #8-bit disp
1517       EMIT(0x70 | cc);
1518       EMIT((offs - short_size) & 0xFF);
1519     } else {
1520       // 0000 1111 1000 tttn #32-bit disp
1521       EMIT(0x0F);
1522       EMIT(0x80 | cc);
1523       emit(offs - long_size);
1524     }
1525   } else if (distance == Label::kNear) {
1526     EMIT(0x70 | cc);
1527     emit_near_disp(L);
1528   } else {
1529     // 0000 1111 1000 tttn #32-bit disp
1530     // Note: could eliminate cond. jumps to this jump if condition
1531     //       is the same however, seems to be rather unlikely case.
1532     EMIT(0x0F);
1533     EMIT(0x80 | cc);
1534     emit_disp(L, Displacement::OTHER);
1535   }
1536 }
1537 
1538 
j(Condition cc,byte * entry,RelocInfo::Mode rmode)1539 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
1540   EnsureSpace ensure_space(this);
1541   DCHECK((0 <= cc) && (static_cast<int>(cc) < 16));
1542   // 0000 1111 1000 tttn #32-bit disp.
1543   EMIT(0x0F);
1544   EMIT(0x80 | cc);
1545   if (RelocInfo::IsRuntimeEntry(rmode)) {
1546     emit(reinterpret_cast<uint32_t>(entry), rmode);
1547   } else {
1548     emit(entry - (pc_ + sizeof(int32_t)), rmode);
1549   }
1550 }
1551 
1552 
j(Condition cc,Handle<Code> code,RelocInfo::Mode rmode)1553 void Assembler::j(Condition cc, Handle<Code> code, RelocInfo::Mode rmode) {
1554   EnsureSpace ensure_space(this);
1555   // 0000 1111 1000 tttn #32-bit disp
1556   EMIT(0x0F);
1557   EMIT(0x80 | cc);
1558   emit(code, rmode);
1559 }
1560 
1561 
1562 // FPU instructions.
1563 
fld(int i)1564 void Assembler::fld(int i) {
1565   EnsureSpace ensure_space(this);
1566   emit_farith(0xD9, 0xC0, i);
1567 }
1568 
1569 
fstp(int i)1570 void Assembler::fstp(int i) {
1571   EnsureSpace ensure_space(this);
1572   emit_farith(0xDD, 0xD8, i);
1573 }
1574 
1575 
fld1()1576 void Assembler::fld1() {
1577   EnsureSpace ensure_space(this);
1578   EMIT(0xD9);
1579   EMIT(0xE8);
1580 }
1581 
1582 
fldpi()1583 void Assembler::fldpi() {
1584   EnsureSpace ensure_space(this);
1585   EMIT(0xD9);
1586   EMIT(0xEB);
1587 }
1588 
1589 
fldz()1590 void Assembler::fldz() {
1591   EnsureSpace ensure_space(this);
1592   EMIT(0xD9);
1593   EMIT(0xEE);
1594 }
1595 
1596 
fldln2()1597 void Assembler::fldln2() {
1598   EnsureSpace ensure_space(this);
1599   EMIT(0xD9);
1600   EMIT(0xED);
1601 }
1602 
1603 
fld_s(const Operand & adr)1604 void Assembler::fld_s(const Operand& adr) {
1605   EnsureSpace ensure_space(this);
1606   EMIT(0xD9);
1607   emit_operand(eax, adr);
1608 }
1609 
1610 
fld_d(const Operand & adr)1611 void Assembler::fld_d(const Operand& adr) {
1612   EnsureSpace ensure_space(this);
1613   EMIT(0xDD);
1614   emit_operand(eax, adr);
1615 }
1616 
1617 
fstp_s(const Operand & adr)1618 void Assembler::fstp_s(const Operand& adr) {
1619   EnsureSpace ensure_space(this);
1620   EMIT(0xD9);
1621   emit_operand(ebx, adr);
1622 }
1623 
1624 
fst_s(const Operand & adr)1625 void Assembler::fst_s(const Operand& adr) {
1626   EnsureSpace ensure_space(this);
1627   EMIT(0xD9);
1628   emit_operand(edx, adr);
1629 }
1630 
1631 
fldcw(const Operand & adr)1632 void Assembler::fldcw(const Operand& adr) {
1633   EnsureSpace ensure_space(this);
1634   EMIT(0xD9);
1635   emit_operand(ebp, adr);
1636 }
1637 
1638 
fnstcw(const Operand & adr)1639 void Assembler::fnstcw(const Operand& adr) {
1640   EnsureSpace ensure_space(this);
1641   EMIT(0xD9);
1642   emit_operand(edi, adr);
1643 }
1644 
1645 
fstp_d(const Operand & adr)1646 void Assembler::fstp_d(const Operand& adr) {
1647   EnsureSpace ensure_space(this);
1648   EMIT(0xDD);
1649   emit_operand(ebx, adr);
1650 }
1651 
1652 
fst_d(const Operand & adr)1653 void Assembler::fst_d(const Operand& adr) {
1654   EnsureSpace ensure_space(this);
1655   EMIT(0xDD);
1656   emit_operand(edx, adr);
1657 }
1658 
1659 
fild_s(const Operand & adr)1660 void Assembler::fild_s(const Operand& adr) {
1661   EnsureSpace ensure_space(this);
1662   EMIT(0xDB);
1663   emit_operand(eax, adr);
1664 }
1665 
1666 
fild_d(const Operand & adr)1667 void Assembler::fild_d(const Operand& adr) {
1668   EnsureSpace ensure_space(this);
1669   EMIT(0xDF);
1670   emit_operand(ebp, adr);
1671 }
1672 
1673 
fistp_s(const Operand & adr)1674 void Assembler::fistp_s(const Operand& adr) {
1675   EnsureSpace ensure_space(this);
1676   EMIT(0xDB);
1677   emit_operand(ebx, adr);
1678 }
1679 
1680 
fisttp_s(const Operand & adr)1681 void Assembler::fisttp_s(const Operand& adr) {
1682   DCHECK(IsEnabled(SSE3));
1683   EnsureSpace ensure_space(this);
1684   EMIT(0xDB);
1685   emit_operand(ecx, adr);
1686 }
1687 
1688 
fisttp_d(const Operand & adr)1689 void Assembler::fisttp_d(const Operand& adr) {
1690   DCHECK(IsEnabled(SSE3));
1691   EnsureSpace ensure_space(this);
1692   EMIT(0xDD);
1693   emit_operand(ecx, adr);
1694 }
1695 
1696 
fist_s(const Operand & adr)1697 void Assembler::fist_s(const Operand& adr) {
1698   EnsureSpace ensure_space(this);
1699   EMIT(0xDB);
1700   emit_operand(edx, adr);
1701 }
1702 
1703 
fistp_d(const Operand & adr)1704 void Assembler::fistp_d(const Operand& adr) {
1705   EnsureSpace ensure_space(this);
1706   EMIT(0xDF);
1707   emit_operand(edi, adr);
1708 }
1709 
1710 
fabs()1711 void Assembler::fabs() {
1712   EnsureSpace ensure_space(this);
1713   EMIT(0xD9);
1714   EMIT(0xE1);
1715 }
1716 
1717 
fchs()1718 void Assembler::fchs() {
1719   EnsureSpace ensure_space(this);
1720   EMIT(0xD9);
1721   EMIT(0xE0);
1722 }
1723 
1724 
fsqrt()1725 void Assembler::fsqrt() {
1726   EnsureSpace ensure_space(this);
1727   EMIT(0xD9);
1728   EMIT(0xFA);
1729 }
1730 
1731 
fcos()1732 void Assembler::fcos() {
1733   EnsureSpace ensure_space(this);
1734   EMIT(0xD9);
1735   EMIT(0xFF);
1736 }
1737 
1738 
fsin()1739 void Assembler::fsin() {
1740   EnsureSpace ensure_space(this);
1741   EMIT(0xD9);
1742   EMIT(0xFE);
1743 }
1744 
1745 
fptan()1746 void Assembler::fptan() {
1747   EnsureSpace ensure_space(this);
1748   EMIT(0xD9);
1749   EMIT(0xF2);
1750 }
1751 
1752 
fyl2x()1753 void Assembler::fyl2x() {
1754   EnsureSpace ensure_space(this);
1755   EMIT(0xD9);
1756   EMIT(0xF1);
1757 }
1758 
1759 
f2xm1()1760 void Assembler::f2xm1() {
1761   EnsureSpace ensure_space(this);
1762   EMIT(0xD9);
1763   EMIT(0xF0);
1764 }
1765 
1766 
fscale()1767 void Assembler::fscale() {
1768   EnsureSpace ensure_space(this);
1769   EMIT(0xD9);
1770   EMIT(0xFD);
1771 }
1772 
1773 
fninit()1774 void Assembler::fninit() {
1775   EnsureSpace ensure_space(this);
1776   EMIT(0xDB);
1777   EMIT(0xE3);
1778 }
1779 
1780 
fadd(int i)1781 void Assembler::fadd(int i) {
1782   EnsureSpace ensure_space(this);
1783   emit_farith(0xDC, 0xC0, i);
1784 }
1785 
1786 
fadd_i(int i)1787 void Assembler::fadd_i(int i) {
1788   EnsureSpace ensure_space(this);
1789   emit_farith(0xD8, 0xC0, i);
1790 }
1791 
1792 
fadd_d(const Operand & adr)1793 void Assembler::fadd_d(const Operand& adr) {
1794   EnsureSpace ensure_space(this);
1795   EMIT(0xDC);
1796   emit_operand(eax, adr);
1797 }
1798 
1799 
fsub(int i)1800 void Assembler::fsub(int i) {
1801   EnsureSpace ensure_space(this);
1802   emit_farith(0xDC, 0xE8, i);
1803 }
1804 
1805 
fsub_i(int i)1806 void Assembler::fsub_i(int i) {
1807   EnsureSpace ensure_space(this);
1808   emit_farith(0xD8, 0xE0, i);
1809 }
1810 
1811 
fsubr_d(const Operand & adr)1812 void Assembler::fsubr_d(const Operand& adr) {
1813   EnsureSpace ensure_space(this);
1814   EMIT(0xDC);
1815   emit_operand(ebp, adr);
1816 }
1817 
1818 
fsub_d(const Operand & adr)1819 void Assembler::fsub_d(const Operand& adr) {
1820   EnsureSpace ensure_space(this);
1821   EMIT(0xDC);
1822   emit_operand(esp, adr);
1823 }
1824 
1825 
fisub_s(const Operand & adr)1826 void Assembler::fisub_s(const Operand& adr) {
1827   EnsureSpace ensure_space(this);
1828   EMIT(0xDA);
1829   emit_operand(esp, adr);
1830 }
1831 
1832 
fmul_i(int i)1833 void Assembler::fmul_i(int i) {
1834   EnsureSpace ensure_space(this);
1835   emit_farith(0xD8, 0xC8, i);
1836 }
1837 
1838 
fmul(int i)1839 void Assembler::fmul(int i) {
1840   EnsureSpace ensure_space(this);
1841   emit_farith(0xDC, 0xC8, i);
1842 }
1843 
1844 
fmul_d(const Operand & adr)1845 void Assembler::fmul_d(const Operand& adr) {
1846   EnsureSpace ensure_space(this);
1847   EMIT(0xDC);
1848   emit_operand(ecx, adr);
1849 }
1850 
1851 
fdiv(int i)1852 void Assembler::fdiv(int i) {
1853   EnsureSpace ensure_space(this);
1854   emit_farith(0xDC, 0xF8, i);
1855 }
1856 
1857 
fdiv_d(const Operand & adr)1858 void Assembler::fdiv_d(const Operand& adr) {
1859   EnsureSpace ensure_space(this);
1860   EMIT(0xDC);
1861   emit_operand(esi, adr);
1862 }
1863 
1864 
fdivr_d(const Operand & adr)1865 void Assembler::fdivr_d(const Operand& adr) {
1866   EnsureSpace ensure_space(this);
1867   EMIT(0xDC);
1868   emit_operand(edi, adr);
1869 }
1870 
1871 
fdiv_i(int i)1872 void Assembler::fdiv_i(int i) {
1873   EnsureSpace ensure_space(this);
1874   emit_farith(0xD8, 0xF0, i);
1875 }
1876 
1877 
faddp(int i)1878 void Assembler::faddp(int i) {
1879   EnsureSpace ensure_space(this);
1880   emit_farith(0xDE, 0xC0, i);
1881 }
1882 
1883 
fsubp(int i)1884 void Assembler::fsubp(int i) {
1885   EnsureSpace ensure_space(this);
1886   emit_farith(0xDE, 0xE8, i);
1887 }
1888 
1889 
fsubrp(int i)1890 void Assembler::fsubrp(int i) {
1891   EnsureSpace ensure_space(this);
1892   emit_farith(0xDE, 0xE0, i);
1893 }
1894 
1895 
fmulp(int i)1896 void Assembler::fmulp(int i) {
1897   EnsureSpace ensure_space(this);
1898   emit_farith(0xDE, 0xC8, i);
1899 }
1900 
1901 
fdivp(int i)1902 void Assembler::fdivp(int i) {
1903   EnsureSpace ensure_space(this);
1904   emit_farith(0xDE, 0xF8, i);
1905 }
1906 
1907 
fprem()1908 void Assembler::fprem() {
1909   EnsureSpace ensure_space(this);
1910   EMIT(0xD9);
1911   EMIT(0xF8);
1912 }
1913 
1914 
fprem1()1915 void Assembler::fprem1() {
1916   EnsureSpace ensure_space(this);
1917   EMIT(0xD9);
1918   EMIT(0xF5);
1919 }
1920 
1921 
fxch(int i)1922 void Assembler::fxch(int i) {
1923   EnsureSpace ensure_space(this);
1924   emit_farith(0xD9, 0xC8, i);
1925 }
1926 
1927 
fincstp()1928 void Assembler::fincstp() {
1929   EnsureSpace ensure_space(this);
1930   EMIT(0xD9);
1931   EMIT(0xF7);
1932 }
1933 
1934 
ffree(int i)1935 void Assembler::ffree(int i) {
1936   EnsureSpace ensure_space(this);
1937   emit_farith(0xDD, 0xC0, i);
1938 }
1939 
1940 
ftst()1941 void Assembler::ftst() {
1942   EnsureSpace ensure_space(this);
1943   EMIT(0xD9);
1944   EMIT(0xE4);
1945 }
1946 
1947 
fxam()1948 void Assembler::fxam() {
1949   EnsureSpace ensure_space(this);
1950   EMIT(0xD9);
1951   EMIT(0xE5);
1952 }
1953 
1954 
fucomp(int i)1955 void Assembler::fucomp(int i) {
1956   EnsureSpace ensure_space(this);
1957   emit_farith(0xDD, 0xE8, i);
1958 }
1959 
1960 
fucompp()1961 void Assembler::fucompp() {
1962   EnsureSpace ensure_space(this);
1963   EMIT(0xDA);
1964   EMIT(0xE9);
1965 }
1966 
1967 
fucomi(int i)1968 void Assembler::fucomi(int i) {
1969   EnsureSpace ensure_space(this);
1970   EMIT(0xDB);
1971   EMIT(0xE8 + i);
1972 }
1973 
1974 
fucomip()1975 void Assembler::fucomip() {
1976   EnsureSpace ensure_space(this);
1977   EMIT(0xDF);
1978   EMIT(0xE9);
1979 }
1980 
1981 
fcompp()1982 void Assembler::fcompp() {
1983   EnsureSpace ensure_space(this);
1984   EMIT(0xDE);
1985   EMIT(0xD9);
1986 }
1987 
1988 
fnstsw_ax()1989 void Assembler::fnstsw_ax() {
1990   EnsureSpace ensure_space(this);
1991   EMIT(0xDF);
1992   EMIT(0xE0);
1993 }
1994 
1995 
fwait()1996 void Assembler::fwait() {
1997   EnsureSpace ensure_space(this);
1998   EMIT(0x9B);
1999 }
2000 
2001 
frndint()2002 void Assembler::frndint() {
2003   EnsureSpace ensure_space(this);
2004   EMIT(0xD9);
2005   EMIT(0xFC);
2006 }
2007 
2008 
fnclex()2009 void Assembler::fnclex() {
2010   EnsureSpace ensure_space(this);
2011   EMIT(0xDB);
2012   EMIT(0xE2);
2013 }
2014 
2015 
fnsave(const Operand & adr)2016 void Assembler::fnsave(const Operand& adr) {
2017   EnsureSpace ensure_space(this);
2018   EMIT(0xDD);
2019   emit_operand(esi, adr);
2020 }
2021 
2022 
frstor(const Operand & adr)2023 void Assembler::frstor(const Operand& adr) {
2024   EnsureSpace ensure_space(this);
2025   EMIT(0xDD);
2026   emit_operand(esp, adr);
2027 }
2028 
2029 
sahf()2030 void Assembler::sahf() {
2031   EnsureSpace ensure_space(this);
2032   EMIT(0x9E);
2033 }
2034 
2035 
setcc(Condition cc,Register reg)2036 void Assembler::setcc(Condition cc, Register reg) {
2037   DCHECK(reg.is_byte_register());
2038   EnsureSpace ensure_space(this);
2039   EMIT(0x0F);
2040   EMIT(0x90 | cc);
2041   EMIT(0xC0 | reg.code());
2042 }
2043 
2044 
GrowBuffer()2045 void Assembler::GrowBuffer() {
2046   DCHECK(buffer_overflow());
2047   if (!own_buffer_) FATAL("external code buffer is too small");
2048 
2049   // Compute new buffer size.
2050   CodeDesc desc;  // the new buffer
2051   desc.buffer_size = 2 * buffer_size_;
2052 
2053   // Some internal data structures overflow for very large buffers,
2054   // they must ensure that kMaximalBufferSize is not too large.
2055   if (desc.buffer_size > kMaximalBufferSize ||
2056       static_cast<size_t>(desc.buffer_size) >
2057           isolate()->heap()->MaxOldGenerationSize()) {
2058     V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2059   }
2060 
2061   // Set up new buffer.
2062   desc.buffer = NewArray<byte>(desc.buffer_size);
2063   desc.origin = this;
2064   desc.instr_size = pc_offset();
2065   desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2066 
2067   // Clear the buffer in debug mode. Use 'int3' instructions to make
2068   // sure to get into problems if we ever run uninitialized code.
2069 #ifdef DEBUG
2070   memset(desc.buffer, 0xCC, desc.buffer_size);
2071 #endif
2072 
2073   // Copy the data.
2074   int pc_delta = desc.buffer - buffer_;
2075   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2076   MemMove(desc.buffer, buffer_, desc.instr_size);
2077   MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
2078           desc.reloc_size);
2079 
2080   DeleteArray(buffer_);
2081   buffer_ = desc.buffer;
2082   buffer_size_ = desc.buffer_size;
2083   pc_ += pc_delta;
2084   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2085                                reloc_info_writer.last_pc() + pc_delta);
2086 
2087   // Relocate internal references.
2088   for (auto pos : internal_reference_positions_) {
2089     int32_t* p = reinterpret_cast<int32_t*>(buffer_ + pos);
2090     *p += pc_delta;
2091   }
2092 
2093   DCHECK(!buffer_overflow());
2094 }
2095 
2096 
emit_arith_b(int op1,int op2,Register dst,int imm8)2097 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
2098   DCHECK(is_uint8(op1) && is_uint8(op2));  // wrong opcode
2099   DCHECK(is_uint8(imm8));
2100   DCHECK((op1 & 0x01) == 0);  // should be 8bit operation
2101   EMIT(op1);
2102   EMIT(op2 | dst.code());
2103   EMIT(imm8);
2104 }
2105 
2106 
emit_arith(int sel,Operand dst,const Immediate & x)2107 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
2108   DCHECK((0 <= sel) && (sel <= 7));
2109   Register ireg = { sel };
2110   if (x.is_int8()) {
2111     EMIT(0x83);  // using a sign-extended 8-bit immediate.
2112     emit_operand(ireg, dst);
2113     EMIT(x.x_ & 0xFF);
2114   } else if (dst.is_reg(eax)) {
2115     EMIT((sel << 3) | 0x05);  // short form if the destination is eax.
2116     emit(x);
2117   } else {
2118     EMIT(0x81);  // using a literal 32-bit immediate.
2119     emit_operand(ireg, dst);
2120     emit(x);
2121   }
2122 }
2123 
2124 
emit_operand(Register reg,const Operand & adr)2125 void Assembler::emit_operand(Register reg, const Operand& adr) {
2126   const unsigned length = adr.len_;
2127   DCHECK(length > 0);
2128 
2129   // Emit updated ModRM byte containing the given register.
2130   pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2131 
2132   // Emit the rest of the encoded operand.
2133   for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2134   pc_ += length;
2135 
2136   // Emit relocation information if necessary.
2137   if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
2138     pc_ -= sizeof(int32_t);  // pc_ must be *at* disp32
2139     RecordRelocInfo(adr.rmode_);
2140     if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) {  // Fixup for labels
2141       emit_label(*reinterpret_cast<Label**>(pc_));
2142     } else {
2143       pc_ += sizeof(int32_t);
2144     }
2145   }
2146 }
2147 
2148 
emit_label(Label * label)2149 void Assembler::emit_label(Label* label) {
2150   if (label->is_bound()) {
2151     internal_reference_positions_.push_back(pc_offset());
2152     emit(reinterpret_cast<uint32_t>(buffer_ + label->pos()));
2153   } else {
2154     emit_disp(label, Displacement::CODE_ABSOLUTE);
2155   }
2156 }
2157 
2158 
emit_farith(int b1,int b2,int i)2159 void Assembler::emit_farith(int b1, int b2, int i) {
2160   DCHECK(is_uint8(b1) && is_uint8(b2));  // wrong opcode
2161   DCHECK(0 <= i &&  i < 8);  // illegal stack offset
2162   EMIT(b1);
2163   EMIT(b2 + i);
2164 }
2165 
2166 
db(uint8_t data)2167 void Assembler::db(uint8_t data) {
2168   EnsureSpace ensure_space(this);
2169   EMIT(data);
2170 }
2171 
2172 
dd(uint32_t data)2173 void Assembler::dd(uint32_t data) {
2174   EnsureSpace ensure_space(this);
2175   emit(data);
2176 }
2177 
2178 
dq(uint64_t data)2179 void Assembler::dq(uint64_t data) {
2180   EnsureSpace ensure_space(this);
2181   emit_q(data);
2182 }
2183 
2184 
dd(Label * label)2185 void Assembler::dd(Label* label) {
2186   EnsureSpace ensure_space(this);
2187   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2188   emit_label(label);
2189 }
2190 
2191 
RecordRelocInfo(RelocInfo::Mode rmode,intptr_t data)2192 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2193   DCHECK(!RelocInfo::IsNone(rmode));
2194   // Don't record external references unless the heap will be serialized.
2195   if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2196       !serializer_enabled() && !emit_debug_code()) {
2197       return;
2198   }
2199   RelocInfo rinfo(isolate(), pc_, rmode, data, NULL);
2200   reloc_info_writer.Write(&rinfo);
2201 }
2202 
2203 }  // namespace internal
2204 }  // namespace v8
2205 
2206 #endif  // V8_TARGET_ARCH_X87
2207