The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / ia32 / assembler-ia32.cc @ f230a1cf

History | View | Annotate | Download (56.6 KB)

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 "v8.h"
38

    
39
#if V8_TARGET_ARCH_IA32
40

    
41
#include "disassembler.h"
42
#include "macro-assembler.h"
43
#include "serialize.h"
44

    
45
namespace v8 {
46
namespace internal {
47

    
48
// -----------------------------------------------------------------------------
49
// Implementation of CpuFeatures
50

    
51
#ifdef DEBUG
52
bool CpuFeatures::initialized_ = false;
53
#endif
54
uint64_t CpuFeatures::supported_ = 0;
55
uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0;
56
uint64_t CpuFeatures::cross_compile_ = 0;
57

    
58

    
59
ExternalReference ExternalReference::cpu_features() {
60
  ASSERT(CpuFeatures::initialized_);
61
  return ExternalReference(&CpuFeatures::supported_);
62
}
63

    
64

    
65
int IntelDoubleRegister::NumAllocatableRegisters() {
66
  if (CpuFeatures::IsSupported(SSE2)) {
67
    return XMMRegister::kNumAllocatableRegisters;
68
  } else {
69
    return X87Register::kNumAllocatableRegisters;
70
  }
71
}
72

    
73

    
74
int IntelDoubleRegister::NumRegisters() {
75
  if (CpuFeatures::IsSupported(SSE2)) {
76
    return XMMRegister::kNumRegisters;
77
  } else {
78
    return X87Register::kNumRegisters;
79
  }
80
}
81

    
82

    
83
const char* IntelDoubleRegister::AllocationIndexToString(int index) {
84
  if (CpuFeatures::IsSupported(SSE2)) {
85
    return XMMRegister::AllocationIndexToString(index);
86
  } else {
87
    return X87Register::AllocationIndexToString(index);
88
  }
89
}
90

    
91

    
92
// The Probe method needs executable memory, so it uses Heap::CreateCode.
93
// Allocation failure is silent and leads to safe default.
94
void CpuFeatures::Probe() {
95
  ASSERT(!initialized_);
96
  ASSERT(supported_ == 0);
97
#ifdef DEBUG
98
  initialized_ = true;
99
#endif
100
  if (Serializer::enabled()) {
101
    supported_ |= OS::CpuFeaturesImpliedByPlatform();
102
    return;  // No features if we might serialize.
103
  }
104

    
105
  uint64_t probed_features = 0;
106
  CPU cpu;
107
  if (cpu.has_sse41()) {
108
    probed_features |= static_cast<uint64_t>(1) << SSE4_1;
109
  }
110
  if (cpu.has_sse3()) {
111
    probed_features |= static_cast<uint64_t>(1) << SSE3;
112
  }
113
  if (cpu.has_sse2()) {
114
    probed_features |= static_cast<uint64_t>(1) << SSE2;
115
  }
116
  if (cpu.has_cmov()) {
117
    probed_features |= static_cast<uint64_t>(1) << CMOV;
118
  }
119

    
120
  // SAHF must be available in compat/legacy mode.
121
  ASSERT(cpu.has_sahf());
122
  probed_features |= static_cast<uint64_t>(1) << SAHF;
123

    
124
  uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform();
125
  supported_ = probed_features | platform_features;
126
  found_by_runtime_probing_only_ = probed_features & ~platform_features;
127
}
128

    
129

    
130
// -----------------------------------------------------------------------------
131
// Implementation of Displacement
132

    
133
void Displacement::init(Label* L, Type type) {
134
  ASSERT(!L->is_bound());
135
  int next = 0;
136
  if (L->is_linked()) {
137
    next = L->pos();
138
    ASSERT(next > 0);  // Displacements must be at positions > 0
139
  }
140
  // Ensure that we _never_ overflow the next field.
141
  ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize));
142
  data_ = NextField::encode(next) | TypeField::encode(type);
143
}
144

    
145

    
146
// -----------------------------------------------------------------------------
147
// Implementation of RelocInfo
148

    
149

    
150
const int RelocInfo::kApplyMask =
151
  RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
152
    1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
153
    1 << RelocInfo::DEBUG_BREAK_SLOT | 1 << RelocInfo::CODE_AGE_SEQUENCE;
154

    
155

    
156
bool RelocInfo::IsCodedSpecially() {
157
  // The deserializer needs to know whether a pointer is specially coded.  Being
158
  // specially coded on IA32 means that it is a relative address, as used by
159
  // branch instructions.  These are also the ones that need changing when a
160
  // code object moves.
161
  return (1 << rmode_) & kApplyMask;
162
}
163

    
164

    
165
void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
166
  // Patch the code at the current address with the supplied instructions.
167
  for (int i = 0; i < instruction_count; i++) {
168
    *(pc_ + i) = *(instructions + i);
169
  }
170

    
171
  // Indicate that code has changed.
172
  CPU::FlushICache(pc_, instruction_count);
173
}
174

    
175

    
176
// Patch the code at the current PC with a call to the target address.
177
// Additional guard int3 instructions can be added if required.
178
void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
179
  // Call instruction takes up 5 bytes and int3 takes up one byte.
180
  static const int kCallCodeSize = 5;
181
  int code_size = kCallCodeSize + guard_bytes;
182

    
183
  // Create a code patcher.
184
  CodePatcher patcher(pc_, code_size);
185

    
186
  // Add a label for checking the size of the code used for returning.
187
#ifdef DEBUG
188
  Label check_codesize;
189
  patcher.masm()->bind(&check_codesize);
190
#endif
191

    
192
  // Patch the code.
193
  patcher.masm()->call(target, RelocInfo::NONE32);
194

    
195
  // Check that the size of the code generated is as expected.
196
  ASSERT_EQ(kCallCodeSize,
197
            patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
198

    
199
  // Add the requested number of int3 instructions after the call.
200
  ASSERT_GE(guard_bytes, 0);
201
  for (int i = 0; i < guard_bytes; i++) {
202
    patcher.masm()->int3();
203
  }
204
}
205

    
206

    
207
// -----------------------------------------------------------------------------
208
// Implementation of Operand
209

    
210
Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
211
  // [base + disp/r]
212
  if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
213
    // [base]
214
    set_modrm(0, base);
215
    if (base.is(esp)) set_sib(times_1, esp, base);
216
  } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
217
    // [base + disp8]
218
    set_modrm(1, base);
219
    if (base.is(esp)) set_sib(times_1, esp, base);
220
    set_disp8(disp);
221
  } else {
222
    // [base + disp/r]
223
    set_modrm(2, base);
224
    if (base.is(esp)) set_sib(times_1, esp, base);
225
    set_dispr(disp, rmode);
226
  }
227
}
228

    
229

    
230
Operand::Operand(Register base,
231
                 Register index,
232
                 ScaleFactor scale,
233
                 int32_t disp,
234
                 RelocInfo::Mode rmode) {
235
  ASSERT(!index.is(esp));  // illegal addressing mode
236
  // [base + index*scale + disp/r]
237
  if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
238
    // [base + index*scale]
239
    set_modrm(0, esp);
240
    set_sib(scale, index, base);
241
  } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
242
    // [base + index*scale + disp8]
243
    set_modrm(1, esp);
244
    set_sib(scale, index, base);
245
    set_disp8(disp);
246
  } else {
247
    // [base + index*scale + disp/r]
248
    set_modrm(2, esp);
249
    set_sib(scale, index, base);
250
    set_dispr(disp, rmode);
251
  }
252
}
253

    
254

    
255
Operand::Operand(Register index,
256
                 ScaleFactor scale,
257
                 int32_t disp,
258
                 RelocInfo::Mode rmode) {
259
  ASSERT(!index.is(esp));  // illegal addressing mode
260
  // [index*scale + disp/r]
261
  set_modrm(0, esp);
262
  set_sib(scale, index, ebp);
263
  set_dispr(disp, rmode);
264
}
265

    
266

    
267
bool Operand::is_reg(Register reg) const {
268
  return ((buf_[0] & 0xF8) == 0xC0)  // addressing mode is register only.
269
      && ((buf_[0] & 0x07) == reg.code());  // register codes match.
270
}
271

    
272

    
273
bool Operand::is_reg_only() const {
274
  return (buf_[0] & 0xF8) == 0xC0;  // Addressing mode is register only.
275
}
276

    
277

    
278
Register Operand::reg() const {
279
  ASSERT(is_reg_only());
280
  return Register::from_code(buf_[0] & 0x07);
281
}
282

    
283

    
284
// -----------------------------------------------------------------------------
285
// Implementation of Assembler.
286

    
287
// Emit a single byte. Must always be inlined.
288
#define EMIT(x)                                 \
289
  *pc_++ = (x)
290

    
291

    
292
#ifdef GENERATED_CODE_COVERAGE
293
static void InitCoverageLog();
294
#endif
295

    
296
Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
297
    : AssemblerBase(isolate, buffer, buffer_size),
298
      positions_recorder_(this) {
299
  // Clear the buffer in debug mode unless it was provided by the
300
  // caller in which case we can't be sure it's okay to overwrite
301
  // existing code in it; see CodePatcher::CodePatcher(...).
302
#ifdef DEBUG
303
  if (own_buffer_) {
304
    memset(buffer_, 0xCC, buffer_size_);  // int3
305
  }
306
#endif
307

    
308
  reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
309

    
310
#ifdef GENERATED_CODE_COVERAGE
311
  InitCoverageLog();
312
#endif
313
}
314

    
315

    
316
void Assembler::GetCode(CodeDesc* desc) {
317
  // Finalize code (at this point overflow() may be true, but the gap ensures
318
  // that we are still not overlapping instructions and relocation info).
319
  ASSERT(pc_ <= reloc_info_writer.pos());  // No overlap.
320
  // Set up code descriptor.
321
  desc->buffer = buffer_;
322
  desc->buffer_size = buffer_size_;
323
  desc->instr_size = pc_offset();
324
  desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
325
  desc->origin = this;
326
}
327

    
328

    
329
void Assembler::Align(int m) {
330
  ASSERT(IsPowerOf2(m));
331
  int mask = m - 1;
332
  int addr = pc_offset();
333
  Nop((m - (addr & mask)) & mask);
334
}
335

    
336

    
337
bool Assembler::IsNop(Address addr) {
338
  Address a = addr;
339
  while (*a == 0x66) a++;
340
  if (*a == 0x90) return true;
341
  if (a[0] == 0xf && a[1] == 0x1f) return true;
342
  return false;
343
}
344

    
345

    
346
void Assembler::Nop(int bytes) {
347
  EnsureSpace ensure_space(this);
348

    
349
  if (!CpuFeatures::IsSupported(SSE2)) {
350
    // Older CPUs that do not support SSE2 may not support multibyte NOP
351
    // instructions.
352
    for (; bytes > 0; bytes--) {
353
      EMIT(0x90);
354
    }
355
    return;
356
  }
357

    
358
  // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
359
  while (bytes > 0) {
360
    switch (bytes) {
361
      case 2:
362
        EMIT(0x66);
363
      case 1:
364
        EMIT(0x90);
365
        return;
366
      case 3:
367
        EMIT(0xf);
368
        EMIT(0x1f);
369
        EMIT(0);
370
        return;
371
      case 4:
372
        EMIT(0xf);
373
        EMIT(0x1f);
374
        EMIT(0x40);
375
        EMIT(0);
376
        return;
377
      case 6:
378
        EMIT(0x66);
379
      case 5:
380
        EMIT(0xf);
381
        EMIT(0x1f);
382
        EMIT(0x44);
383
        EMIT(0);
384
        EMIT(0);
385
        return;
386
      case 7:
387
        EMIT(0xf);
388
        EMIT(0x1f);
389
        EMIT(0x80);
390
        EMIT(0);
391
        EMIT(0);
392
        EMIT(0);
393
        EMIT(0);
394
        return;
395
      default:
396
      case 11:
397
        EMIT(0x66);
398
        bytes--;
399
      case 10:
400
        EMIT(0x66);
401
        bytes--;
402
      case 9:
403
        EMIT(0x66);
404
        bytes--;
405
      case 8:
406
        EMIT(0xf);
407
        EMIT(0x1f);
408
        EMIT(0x84);
409
        EMIT(0);
410
        EMIT(0);
411
        EMIT(0);
412
        EMIT(0);
413
        EMIT(0);
414
        bytes -= 8;
415
    }
416
  }
417
}
418

    
419

    
420
void Assembler::CodeTargetAlign() {
421
  Align(16);  // Preferred alignment of jump targets on ia32.
422
}
423

    
424

    
425
void Assembler::cpuid() {
426
  EnsureSpace ensure_space(this);
427
  EMIT(0x0F);
428
  EMIT(0xA2);
429
}
430

    
431

    
432
void Assembler::pushad() {
433
  EnsureSpace ensure_space(this);
434
  EMIT(0x60);
435
}
436

    
437

    
438
void Assembler::popad() {
439
  EnsureSpace ensure_space(this);
440
  EMIT(0x61);
441
}
442

    
443

    
444
void Assembler::pushfd() {
445
  EnsureSpace ensure_space(this);
446
  EMIT(0x9C);
447
}
448

    
449

    
450
void Assembler::popfd() {
451
  EnsureSpace ensure_space(this);
452
  EMIT(0x9D);
453
}
454

    
455

    
456
void Assembler::push(const Immediate& x) {
457
  EnsureSpace ensure_space(this);
458
  if (x.is_int8()) {
459
    EMIT(0x6a);
460
    EMIT(x.x_);
461
  } else {
462
    EMIT(0x68);
463
    emit(x);
464
  }
465
}
466

    
467

    
468
void Assembler::push_imm32(int32_t imm32) {
469
  EnsureSpace ensure_space(this);
470
  EMIT(0x68);
471
  emit(imm32);
472
}
473

    
474

    
475
void Assembler::push(Register src) {
476
  EnsureSpace ensure_space(this);
477
  EMIT(0x50 | src.code());
478
}
479

    
480

    
481
void Assembler::push(const Operand& src) {
482
  EnsureSpace ensure_space(this);
483
  EMIT(0xFF);
484
  emit_operand(esi, src);
485
}
486

    
487

    
488
void Assembler::pop(Register dst) {
489
  ASSERT(reloc_info_writer.last_pc() != NULL);
490
  EnsureSpace ensure_space(this);
491
  EMIT(0x58 | dst.code());
492
}
493

    
494

    
495
void Assembler::pop(const Operand& dst) {
496
  EnsureSpace ensure_space(this);
497
  EMIT(0x8F);
498
  emit_operand(eax, dst);
499
}
500

    
501

    
502
void Assembler::enter(const Immediate& size) {
503
  EnsureSpace ensure_space(this);
504
  EMIT(0xC8);
505
  emit_w(size);
506
  EMIT(0);
507
}
508

    
509

    
510
void Assembler::leave() {
511
  EnsureSpace ensure_space(this);
512
  EMIT(0xC9);
513
}
514

    
515

    
516
void Assembler::mov_b(Register dst, const Operand& src) {
517
  CHECK(dst.is_byte_register());
518
  EnsureSpace ensure_space(this);
519
  EMIT(0x8A);
520
  emit_operand(dst, src);
521
}
522

    
523

    
524
void Assembler::mov_b(const Operand& dst, int8_t imm8) {
525
  EnsureSpace ensure_space(this);
526
  EMIT(0xC6);
527
  emit_operand(eax, dst);
528
  EMIT(imm8);
529
}
530

    
531

    
532
void Assembler::mov_b(const Operand& dst, Register src) {
533
  CHECK(src.is_byte_register());
534
  EnsureSpace ensure_space(this);
535
  EMIT(0x88);
536
  emit_operand(src, dst);
537
}
538

    
539

    
540
void Assembler::mov_w(Register dst, const Operand& src) {
541
  EnsureSpace ensure_space(this);
542
  EMIT(0x66);
543
  EMIT(0x8B);
544
  emit_operand(dst, src);
545
}
546

    
547

    
548
void Assembler::mov_w(const Operand& dst, Register src) {
549
  EnsureSpace ensure_space(this);
550
  EMIT(0x66);
551
  EMIT(0x89);
552
  emit_operand(src, dst);
553
}
554

    
555

    
556
void Assembler::mov(Register dst, int32_t imm32) {
557
  EnsureSpace ensure_space(this);
558
  EMIT(0xB8 | dst.code());
559
  emit(imm32);
560
}
561

    
562

    
563
void Assembler::mov(Register dst, const Immediate& x) {
564
  EnsureSpace ensure_space(this);
565
  EMIT(0xB8 | dst.code());
566
  emit(x);
567
}
568

    
569

    
570
void Assembler::mov(Register dst, Handle<Object> handle) {
571
  EnsureSpace ensure_space(this);
572
  EMIT(0xB8 | dst.code());
573
  emit(handle);
574
}
575

    
576

    
577
void Assembler::mov(Register dst, const Operand& src) {
578
  EnsureSpace ensure_space(this);
579
  EMIT(0x8B);
580
  emit_operand(dst, src);
581
}
582

    
583

    
584
void Assembler::mov(Register dst, Register src) {
585
  EnsureSpace ensure_space(this);
586
  EMIT(0x89);
587
  EMIT(0xC0 | src.code() << 3 | dst.code());
588
}
589

    
590

    
591
void Assembler::mov(const Operand& dst, const Immediate& x) {
592
  EnsureSpace ensure_space(this);
593
  EMIT(0xC7);
594
  emit_operand(eax, dst);
595
  emit(x);
596
}
597

    
598

    
599
void Assembler::mov(const Operand& dst, Handle<Object> handle) {
600
  EnsureSpace ensure_space(this);
601
  EMIT(0xC7);
602
  emit_operand(eax, dst);
603
  emit(handle);
604
}
605

    
606

    
607
void Assembler::mov(const Operand& dst, Register src) {
608
  EnsureSpace ensure_space(this);
609
  EMIT(0x89);
610
  emit_operand(src, dst);
611
}
612

    
613

    
614
void Assembler::movsx_b(Register dst, const Operand& src) {
615
  EnsureSpace ensure_space(this);
616
  EMIT(0x0F);
617
  EMIT(0xBE);
618
  emit_operand(dst, src);
619
}
620

    
621

    
622
void Assembler::movsx_w(Register dst, const Operand& src) {
623
  EnsureSpace ensure_space(this);
624
  EMIT(0x0F);
625
  EMIT(0xBF);
626
  emit_operand(dst, src);
627
}
628

    
629

    
630
void Assembler::movzx_b(Register dst, const Operand& src) {
631
  EnsureSpace ensure_space(this);
632
  EMIT(0x0F);
633
  EMIT(0xB6);
634
  emit_operand(dst, src);
635
}
636

    
637

    
638
void Assembler::movzx_w(Register dst, const Operand& src) {
639
  EnsureSpace ensure_space(this);
640
  EMIT(0x0F);
641
  EMIT(0xB7);
642
  emit_operand(dst, src);
643
}
644

    
645

    
646
void Assembler::cmov(Condition cc, Register dst, const Operand& src) {
647
  ASSERT(IsEnabled(CMOV));
648
  EnsureSpace ensure_space(this);
649
  // Opcode: 0f 40 + cc /r.
650
  EMIT(0x0F);
651
  EMIT(0x40 + cc);
652
  emit_operand(dst, src);
653
}
654

    
655

    
656
void Assembler::cld() {
657
  EnsureSpace ensure_space(this);
658
  EMIT(0xFC);
659
}
660

    
661

    
662
void Assembler::rep_movs() {
663
  EnsureSpace ensure_space(this);
664
  EMIT(0xF3);
665
  EMIT(0xA5);
666
}
667

    
668

    
669
void Assembler::rep_stos() {
670
  EnsureSpace ensure_space(this);
671
  EMIT(0xF3);
672
  EMIT(0xAB);
673
}
674

    
675

    
676
void Assembler::stos() {
677
  EnsureSpace ensure_space(this);
678
  EMIT(0xAB);
679
}
680

    
681

    
682
void Assembler::xchg(Register dst, Register src) {
683
  EnsureSpace ensure_space(this);
684
  if (src.is(eax) || dst.is(eax)) {  // Single-byte encoding.
685
    EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
686
  } else {
687
    EMIT(0x87);
688
    EMIT(0xC0 | src.code() << 3 | dst.code());
689
  }
690
}
691

    
692

    
693
void Assembler::adc(Register dst, int32_t imm32) {
694
  EnsureSpace ensure_space(this);
695
  emit_arith(2, Operand(dst), Immediate(imm32));
696
}
697

    
698

    
699
void Assembler::adc(Register dst, const Operand& src) {
700
  EnsureSpace ensure_space(this);
701
  EMIT(0x13);
702
  emit_operand(dst, src);
703
}
704

    
705

    
706
void Assembler::add(Register dst, const Operand& src) {
707
  EnsureSpace ensure_space(this);
708
  EMIT(0x03);
709
  emit_operand(dst, src);
710
}
711

    
712

    
713
void Assembler::add(const Operand& dst, Register src) {
714
  EnsureSpace ensure_space(this);
715
  EMIT(0x01);
716
  emit_operand(src, dst);
717
}
718

    
719

    
720
void Assembler::add(const Operand& dst, const Immediate& x) {
721
  ASSERT(reloc_info_writer.last_pc() != NULL);
722
  EnsureSpace ensure_space(this);
723
  emit_arith(0, dst, x);
724
}
725

    
726

    
727
void Assembler::and_(Register dst, int32_t imm32) {
728
  and_(dst, Immediate(imm32));
729
}
730

    
731

    
732
void Assembler::and_(Register dst, const Immediate& x) {
733
  EnsureSpace ensure_space(this);
734
  emit_arith(4, Operand(dst), x);
735
}
736

    
737

    
738
void Assembler::and_(Register dst, const Operand& src) {
739
  EnsureSpace ensure_space(this);
740
  EMIT(0x23);
741
  emit_operand(dst, src);
742
}
743

    
744

    
745
void Assembler::and_(const Operand& dst, const Immediate& x) {
746
  EnsureSpace ensure_space(this);
747
  emit_arith(4, dst, x);
748
}
749

    
750

    
751
void Assembler::and_(const Operand& dst, Register src) {
752
  EnsureSpace ensure_space(this);
753
  EMIT(0x21);
754
  emit_operand(src, dst);
755
}
756

    
757

    
758
void Assembler::cmpb(const Operand& op, int8_t imm8) {
759
  EnsureSpace ensure_space(this);
760
  if (op.is_reg(eax)) {
761
    EMIT(0x3C);
762
  } else {
763
    EMIT(0x80);
764
    emit_operand(edi, op);  // edi == 7
765
  }
766
  EMIT(imm8);
767
}
768

    
769

    
770
void Assembler::cmpb(const Operand& op, Register reg) {
771
  CHECK(reg.is_byte_register());
772
  EnsureSpace ensure_space(this);
773
  EMIT(0x38);
774
  emit_operand(reg, op);
775
}
776

    
777

    
778
void Assembler::cmpb(Register reg, const Operand& op) {
779
  CHECK(reg.is_byte_register());
780
  EnsureSpace ensure_space(this);
781
  EMIT(0x3A);
782
  emit_operand(reg, op);
783
}
784

    
785

    
786
void Assembler::cmpw(const Operand& op, Immediate imm16) {
787
  ASSERT(imm16.is_int16());
788
  EnsureSpace ensure_space(this);
789
  EMIT(0x66);
790
  EMIT(0x81);
791
  emit_operand(edi, op);
792
  emit_w(imm16);
793
}
794

    
795

    
796
void Assembler::cmp(Register reg, int32_t imm32) {
797
  EnsureSpace ensure_space(this);
798
  emit_arith(7, Operand(reg), Immediate(imm32));
799
}
800

    
801

    
802
void Assembler::cmp(Register reg, Handle<Object> handle) {
803
  EnsureSpace ensure_space(this);
804
  emit_arith(7, Operand(reg), Immediate(handle));
805
}
806

    
807

    
808
void Assembler::cmp(Register reg, const Operand& op) {
809
  EnsureSpace ensure_space(this);
810
  EMIT(0x3B);
811
  emit_operand(reg, op);
812
}
813

    
814

    
815
void Assembler::cmp(const Operand& op, const Immediate& imm) {
816
  EnsureSpace ensure_space(this);
817
  emit_arith(7, op, imm);
818
}
819

    
820

    
821
void Assembler::cmp(const Operand& op, Handle<Object> handle) {
822
  EnsureSpace ensure_space(this);
823
  emit_arith(7, op, Immediate(handle));
824
}
825

    
826

    
827
void Assembler::cmpb_al(const Operand& op) {
828
  EnsureSpace ensure_space(this);
829
  EMIT(0x38);  // CMP r/m8, r8
830
  emit_operand(eax, op);  // eax has same code as register al.
831
}
832

    
833

    
834
void Assembler::cmpw_ax(const Operand& op) {
835
  EnsureSpace ensure_space(this);
836
  EMIT(0x66);
837
  EMIT(0x39);  // CMP r/m16, r16
838
  emit_operand(eax, op);  // eax has same code as register ax.
839
}
840

    
841

    
842
void Assembler::dec_b(Register dst) {
843
  CHECK(dst.is_byte_register());
844
  EnsureSpace ensure_space(this);
845
  EMIT(0xFE);
846
  EMIT(0xC8 | dst.code());
847
}
848

    
849

    
850
void Assembler::dec_b(const Operand& dst) {
851
  EnsureSpace ensure_space(this);
852
  EMIT(0xFE);
853
  emit_operand(ecx, dst);
854
}
855

    
856

    
857
void Assembler::dec(Register dst) {
858
  EnsureSpace ensure_space(this);
859
  EMIT(0x48 | dst.code());
860
}
861

    
862

    
863
void Assembler::dec(const Operand& dst) {
864
  EnsureSpace ensure_space(this);
865
  EMIT(0xFF);
866
  emit_operand(ecx, dst);
867
}
868

    
869

    
870
void Assembler::cdq() {
871
  EnsureSpace ensure_space(this);
872
  EMIT(0x99);
873
}
874

    
875

    
876
void Assembler::idiv(Register src) {
877
  EnsureSpace ensure_space(this);
878
  EMIT(0xF7);
879
  EMIT(0xF8 | src.code());
880
}
881

    
882

    
883
void Assembler::imul(Register reg) {
884
  EnsureSpace ensure_space(this);
885
  EMIT(0xF7);
886
  EMIT(0xE8 | reg.code());
887
}
888

    
889

    
890
void Assembler::imul(Register dst, const Operand& src) {
891
  EnsureSpace ensure_space(this);
892
  EMIT(0x0F);
893
  EMIT(0xAF);
894
  emit_operand(dst, src);
895
}
896

    
897

    
898
void Assembler::imul(Register dst, Register src, int32_t imm32) {
899
  EnsureSpace ensure_space(this);
900
  if (is_int8(imm32)) {
901
    EMIT(0x6B);
902
    EMIT(0xC0 | dst.code() << 3 | src.code());
903
    EMIT(imm32);
904
  } else {
905
    EMIT(0x69);
906
    EMIT(0xC0 | dst.code() << 3 | src.code());
907
    emit(imm32);
908
  }
909
}
910

    
911

    
912
void Assembler::inc(Register dst) {
913
  EnsureSpace ensure_space(this);
914
  EMIT(0x40 | dst.code());
915
}
916

    
917

    
918
void Assembler::inc(const Operand& dst) {
919
  EnsureSpace ensure_space(this);
920
  EMIT(0xFF);
921
  emit_operand(eax, dst);
922
}
923

    
924

    
925
void Assembler::lea(Register dst, const Operand& src) {
926
  EnsureSpace ensure_space(this);
927
  EMIT(0x8D);
928
  emit_operand(dst, src);
929
}
930

    
931

    
932
void Assembler::mul(Register src) {
933
  EnsureSpace ensure_space(this);
934
  EMIT(0xF7);
935
  EMIT(0xE0 | src.code());
936
}
937

    
938

    
939
void Assembler::neg(Register dst) {
940
  EnsureSpace ensure_space(this);
941
  EMIT(0xF7);
942
  EMIT(0xD8 | dst.code());
943
}
944

    
945

    
946
void Assembler::not_(Register dst) {
947
  EnsureSpace ensure_space(this);
948
  EMIT(0xF7);
949
  EMIT(0xD0 | dst.code());
950
}
951

    
952

    
953
void Assembler::or_(Register dst, int32_t imm32) {
954
  EnsureSpace ensure_space(this);
955
  emit_arith(1, Operand(dst), Immediate(imm32));
956
}
957

    
958

    
959
void Assembler::or_(Register dst, const Operand& src) {
960
  EnsureSpace ensure_space(this);
961
  EMIT(0x0B);
962
  emit_operand(dst, src);
963
}
964

    
965

    
966
void Assembler::or_(const Operand& dst, const Immediate& x) {
967
  EnsureSpace ensure_space(this);
968
  emit_arith(1, dst, x);
969
}
970

    
971

    
972
void Assembler::or_(const Operand& dst, Register src) {
973
  EnsureSpace ensure_space(this);
974
  EMIT(0x09);
975
  emit_operand(src, dst);
976
}
977

    
978

    
979
void Assembler::rcl(Register dst, uint8_t imm8) {
980
  EnsureSpace ensure_space(this);
981
  ASSERT(is_uint5(imm8));  // illegal shift count
982
  if (imm8 == 1) {
983
    EMIT(0xD1);
984
    EMIT(0xD0 | dst.code());
985
  } else {
986
    EMIT(0xC1);
987
    EMIT(0xD0 | dst.code());
988
    EMIT(imm8);
989
  }
990
}
991

    
992

    
993
void Assembler::rcr(Register dst, uint8_t imm8) {
994
  EnsureSpace ensure_space(this);
995
  ASSERT(is_uint5(imm8));  // illegal shift count
996
  if (imm8 == 1) {
997
    EMIT(0xD1);
998
    EMIT(0xD8 | dst.code());
999
  } else {
1000
    EMIT(0xC1);
1001
    EMIT(0xD8 | dst.code());
1002
    EMIT(imm8);
1003
  }
1004
}
1005

    
1006

    
1007
void Assembler::ror(Register dst, uint8_t imm8) {
1008
  EnsureSpace ensure_space(this);
1009
  ASSERT(is_uint5(imm8));  // illegal shift count
1010
  if (imm8 == 1) {
1011
    EMIT(0xD1);
1012
    EMIT(0xC8 | dst.code());
1013
  } else {
1014
    EMIT(0xC1);
1015
    EMIT(0xC8 | dst.code());
1016
    EMIT(imm8);
1017
  }
1018
}
1019

    
1020

    
1021
void Assembler::ror_cl(Register dst) {
1022
  EnsureSpace ensure_space(this);
1023
  EMIT(0xD3);
1024
  EMIT(0xC8 | dst.code());
1025
}
1026

    
1027

    
1028
void Assembler::sar(Register dst, uint8_t imm8) {
1029
  EnsureSpace ensure_space(this);
1030
  ASSERT(is_uint5(imm8));  // illegal shift count
1031
  if (imm8 == 1) {
1032
    EMIT(0xD1);
1033
    EMIT(0xF8 | dst.code());
1034
  } else {
1035
    EMIT(0xC1);
1036
    EMIT(0xF8 | dst.code());
1037
    EMIT(imm8);
1038
  }
1039
}
1040

    
1041

    
1042
void Assembler::sar_cl(Register dst) {
1043
  EnsureSpace ensure_space(this);
1044
  EMIT(0xD3);
1045
  EMIT(0xF8 | dst.code());
1046
}
1047

    
1048

    
1049
void Assembler::sbb(Register dst, const Operand& src) {
1050
  EnsureSpace ensure_space(this);
1051
  EMIT(0x1B);
1052
  emit_operand(dst, src);
1053
}
1054

    
1055

    
1056
void Assembler::shld(Register dst, const Operand& src) {
1057
  EnsureSpace ensure_space(this);
1058
  EMIT(0x0F);
1059
  EMIT(0xA5);
1060
  emit_operand(dst, src);
1061
}
1062

    
1063

    
1064
void Assembler::shl(Register dst, uint8_t imm8) {
1065
  EnsureSpace ensure_space(this);
1066
  ASSERT(is_uint5(imm8));  // illegal shift count
1067
  if (imm8 == 1) {
1068
    EMIT(0xD1);
1069
    EMIT(0xE0 | dst.code());
1070
  } else {
1071
    EMIT(0xC1);
1072
    EMIT(0xE0 | dst.code());
1073
    EMIT(imm8);
1074
  }
1075
}
1076

    
1077

    
1078
void Assembler::shl_cl(Register dst) {
1079
  EnsureSpace ensure_space(this);
1080
  EMIT(0xD3);
1081
  EMIT(0xE0 | dst.code());
1082
}
1083

    
1084

    
1085
void Assembler::shrd(Register dst, const Operand& src) {
1086
  EnsureSpace ensure_space(this);
1087
  EMIT(0x0F);
1088
  EMIT(0xAD);
1089
  emit_operand(dst, src);
1090
}
1091

    
1092

    
1093
void Assembler::shr(Register dst, uint8_t imm8) {
1094
  EnsureSpace ensure_space(this);
1095
  ASSERT(is_uint5(imm8));  // illegal shift count
1096
  if (imm8 == 1) {
1097
    EMIT(0xD1);
1098
    EMIT(0xE8 | dst.code());
1099
  } else {
1100
    EMIT(0xC1);
1101
    EMIT(0xE8 | dst.code());
1102
    EMIT(imm8);
1103
  }
1104
}
1105

    
1106

    
1107
void Assembler::shr_cl(Register dst) {
1108
  EnsureSpace ensure_space(this);
1109
  EMIT(0xD3);
1110
  EMIT(0xE8 | dst.code());
1111
}
1112

    
1113

    
1114
void Assembler::sub(const Operand& dst, const Immediate& x) {
1115
  EnsureSpace ensure_space(this);
1116
  emit_arith(5, dst, x);
1117
}
1118

    
1119

    
1120
void Assembler::sub(Register dst, const Operand& src) {
1121
  EnsureSpace ensure_space(this);
1122
  EMIT(0x2B);
1123
  emit_operand(dst, src);
1124
}
1125

    
1126

    
1127
void Assembler::sub(const Operand& dst, Register src) {
1128
  EnsureSpace ensure_space(this);
1129
  EMIT(0x29);
1130
  emit_operand(src, dst);
1131
}
1132

    
1133

    
1134
void Assembler::test(Register reg, const Immediate& imm) {
1135
  if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1136
    test_b(reg, imm.x_);
1137
    return;
1138
  }
1139

    
1140
  EnsureSpace ensure_space(this);
1141
  // This is not using emit_arith because test doesn't support
1142
  // sign-extension of 8-bit operands.
1143
  if (reg.is(eax)) {
1144
    EMIT(0xA9);
1145
  } else {
1146
    EMIT(0xF7);
1147
    EMIT(0xC0 | reg.code());
1148
  }
1149
  emit(imm);
1150
}
1151

    
1152

    
1153
void Assembler::test(Register reg, const Operand& op) {
1154
  EnsureSpace ensure_space(this);
1155
  EMIT(0x85);
1156
  emit_operand(reg, op);
1157
}
1158

    
1159

    
1160
void Assembler::test_b(Register reg, const Operand& op) {
1161
  CHECK(reg.is_byte_register());
1162
  EnsureSpace ensure_space(this);
1163
  EMIT(0x84);
1164
  emit_operand(reg, op);
1165
}
1166

    
1167

    
1168
void Assembler::test(const Operand& op, const Immediate& imm) {
1169
  if (op.is_reg_only()) {
1170
    test(op.reg(), imm);
1171
    return;
1172
  }
1173
  if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1174
    return test_b(op, imm.x_);
1175
  }
1176
  EnsureSpace ensure_space(this);
1177
  EMIT(0xF7);
1178
  emit_operand(eax, op);
1179
  emit(imm);
1180
}
1181

    
1182

    
1183
void Assembler::test_b(Register reg, uint8_t imm8) {
1184
  EnsureSpace ensure_space(this);
1185
  // Only use test against byte for registers that have a byte
1186
  // variant: eax, ebx, ecx, and edx.
1187
  if (reg.is(eax)) {
1188
    EMIT(0xA8);
1189
    EMIT(imm8);
1190
  } else if (reg.is_byte_register()) {
1191
    emit_arith_b(0xF6, 0xC0, reg, imm8);
1192
  } else {
1193
    EMIT(0xF7);
1194
    EMIT(0xC0 | reg.code());
1195
    emit(imm8);
1196
  }
1197
}
1198

    
1199

    
1200
void Assembler::test_b(const Operand& op, uint8_t imm8) {
1201
  if (op.is_reg_only()) {
1202
    test_b(op.reg(), imm8);
1203
    return;
1204
  }
1205
  EnsureSpace ensure_space(this);
1206
  EMIT(0xF6);
1207
  emit_operand(eax, op);
1208
  EMIT(imm8);
1209
}
1210

    
1211

    
1212
void Assembler::xor_(Register dst, int32_t imm32) {
1213
  EnsureSpace ensure_space(this);
1214
  emit_arith(6, Operand(dst), Immediate(imm32));
1215
}
1216

    
1217

    
1218
void Assembler::xor_(Register dst, const Operand& src) {
1219
  EnsureSpace ensure_space(this);
1220
  EMIT(0x33);
1221
  emit_operand(dst, src);
1222
}
1223

    
1224

    
1225
void Assembler::xor_(const Operand& dst, Register src) {
1226
  EnsureSpace ensure_space(this);
1227
  EMIT(0x31);
1228
  emit_operand(src, dst);
1229
}
1230

    
1231

    
1232
void Assembler::xor_(const Operand& dst, const Immediate& x) {
1233
  EnsureSpace ensure_space(this);
1234
  emit_arith(6, dst, x);
1235
}
1236

    
1237

    
1238
void Assembler::bt(const Operand& dst, Register src) {
1239
  EnsureSpace ensure_space(this);
1240
  EMIT(0x0F);
1241
  EMIT(0xA3);
1242
  emit_operand(src, dst);
1243
}
1244

    
1245

    
1246
void Assembler::bts(const Operand& dst, Register src) {
1247
  EnsureSpace ensure_space(this);
1248
  EMIT(0x0F);
1249
  EMIT(0xAB);
1250
  emit_operand(src, dst);
1251
}
1252

    
1253

    
1254
void Assembler::hlt() {
1255
  EnsureSpace ensure_space(this);
1256
  EMIT(0xF4);
1257
}
1258

    
1259

    
1260
void Assembler::int3() {
1261
  EnsureSpace ensure_space(this);
1262
  EMIT(0xCC);
1263
}
1264

    
1265

    
1266
void Assembler::nop() {
1267
  EnsureSpace ensure_space(this);
1268
  EMIT(0x90);
1269
}
1270

    
1271

    
1272
void Assembler::ret(int imm16) {
1273
  EnsureSpace ensure_space(this);
1274
  ASSERT(is_uint16(imm16));
1275
  if (imm16 == 0) {
1276
    EMIT(0xC3);
1277
  } else {
1278
    EMIT(0xC2);
1279
    EMIT(imm16 & 0xFF);
1280
    EMIT((imm16 >> 8) & 0xFF);
1281
  }
1282
}
1283

    
1284

    
1285
// Labels refer to positions in the (to be) generated code.
1286
// There are bound, linked, and unused labels.
1287
//
1288
// Bound labels refer to known positions in the already
1289
// generated code. pos() is the position the label refers to.
1290
//
1291
// Linked labels refer to unknown positions in the code
1292
// to be generated; pos() is the position of the 32bit
1293
// Displacement of the last instruction using the label.
1294

    
1295

    
1296
void Assembler::print(Label* L) {
1297
  if (L->is_unused()) {
1298
    PrintF("unused label\n");
1299
  } else if (L->is_bound()) {
1300
    PrintF("bound label to %d\n", L->pos());
1301
  } else if (L->is_linked()) {
1302
    Label l = *L;
1303
    PrintF("unbound label");
1304
    while (l.is_linked()) {
1305
      Displacement disp = disp_at(&l);
1306
      PrintF("@ %d ", l.pos());
1307
      disp.print();
1308
      PrintF("\n");
1309
      disp.next(&l);
1310
    }
1311
  } else {
1312
    PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1313
  }
1314
}
1315

    
1316

    
1317
void Assembler::bind_to(Label* L, int pos) {
1318
  EnsureSpace ensure_space(this);
1319
  ASSERT(0 <= pos && pos <= pc_offset());  // must have a valid binding position
1320
  while (L->is_linked()) {
1321
    Displacement disp = disp_at(L);
1322
    int fixup_pos = L->pos();
1323
    if (disp.type() == Displacement::CODE_RELATIVE) {
1324
      // Relative to Code* heap object pointer.
1325
      long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1326
    } else {
1327
      if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1328
        ASSERT(byte_at(fixup_pos - 1) == 0xE9);  // jmp expected
1329
      }
1330
      // Relative address, relative to point after address.
1331
      int imm32 = pos - (fixup_pos + sizeof(int32_t));
1332
      long_at_put(fixup_pos, imm32);
1333
    }
1334
    disp.next(L);
1335
  }
1336
  while (L->is_near_linked()) {
1337
    int fixup_pos = L->near_link_pos();
1338
    int offset_to_next =
1339
        static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
1340
    ASSERT(offset_to_next <= 0);
1341
    // Relative address, relative to point after address.
1342
    int disp = pos - fixup_pos - sizeof(int8_t);
1343
    CHECK(0 <= disp && disp <= 127);
1344
    set_byte_at(fixup_pos, disp);
1345
    if (offset_to_next < 0) {
1346
      L->link_to(fixup_pos + offset_to_next, Label::kNear);
1347
    } else {
1348
      L->UnuseNear();
1349
    }
1350
  }
1351
  L->bind_to(pos);
1352
}
1353

    
1354

    
1355
void Assembler::bind(Label* L) {
1356
  EnsureSpace ensure_space(this);
1357
  ASSERT(!L->is_bound());  // label can only be bound once
1358
  bind_to(L, pc_offset());
1359
}
1360

    
1361

    
1362
void Assembler::call(Label* L) {
1363
  positions_recorder()->WriteRecordedPositions();
1364
  EnsureSpace ensure_space(this);
1365
  if (L->is_bound()) {
1366
    const int long_size = 5;
1367
    int offs = L->pos() - pc_offset();
1368
    ASSERT(offs <= 0);
1369
    // 1110 1000 #32-bit disp.
1370
    EMIT(0xE8);
1371
    emit(offs - long_size);
1372
  } else {
1373
    // 1110 1000 #32-bit disp.
1374
    EMIT(0xE8);
1375
    emit_disp(L, Displacement::OTHER);
1376
  }
1377
}
1378

    
1379

    
1380
void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
1381
  positions_recorder()->WriteRecordedPositions();
1382
  EnsureSpace ensure_space(this);
1383
  ASSERT(!RelocInfo::IsCodeTarget(rmode));
1384
  EMIT(0xE8);
1385
  if (RelocInfo::IsRuntimeEntry(rmode)) {
1386
    emit(reinterpret_cast<uint32_t>(entry), rmode);
1387
  } else {
1388
    emit(entry - (pc_ + sizeof(int32_t)), rmode);
1389
  }
1390
}
1391

    
1392

    
1393
int Assembler::CallSize(const Operand& adr) {
1394
  // Call size is 1 (opcode) + adr.len_ (operand).
1395
  return 1 + adr.len_;
1396
}
1397

    
1398

    
1399
void Assembler::call(const Operand& adr) {
1400
  positions_recorder()->WriteRecordedPositions();
1401
  EnsureSpace ensure_space(this);
1402
  EMIT(0xFF);
1403
  emit_operand(edx, adr);
1404
}
1405

    
1406

    
1407
int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1408
  return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
1409
}
1410

    
1411

    
1412
void Assembler::call(Handle<Code> code,
1413
                     RelocInfo::Mode rmode,
1414
                     TypeFeedbackId ast_id) {
1415
  positions_recorder()->WriteRecordedPositions();
1416
  EnsureSpace ensure_space(this);
1417
  ASSERT(RelocInfo::IsCodeTarget(rmode)
1418
      || rmode == RelocInfo::CODE_AGE_SEQUENCE);
1419
  EMIT(0xE8);
1420
  emit(code, rmode, ast_id);
1421
}
1422

    
1423

    
1424
void Assembler::jmp(Label* L, Label::Distance distance) {
1425
  EnsureSpace ensure_space(this);
1426
  if (L->is_bound()) {
1427
    const int short_size = 2;
1428
    const int long_size  = 5;
1429
    int offs = L->pos() - pc_offset();
1430
    ASSERT(offs <= 0);
1431
    if (is_int8(offs - short_size)) {
1432
      // 1110 1011 #8-bit disp.
1433
      EMIT(0xEB);
1434
      EMIT((offs - short_size) & 0xFF);
1435
    } else {
1436
      // 1110 1001 #32-bit disp.
1437
      EMIT(0xE9);
1438
      emit(offs - long_size);
1439
    }
1440
  } else if (distance == Label::kNear) {
1441
    EMIT(0xEB);
1442
    emit_near_disp(L);
1443
  } else {
1444
    // 1110 1001 #32-bit disp.
1445
    EMIT(0xE9);
1446
    emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1447
  }
1448
}
1449

    
1450

    
1451
void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
1452
  EnsureSpace ensure_space(this);
1453
  ASSERT(!RelocInfo::IsCodeTarget(rmode));
1454
  EMIT(0xE9);
1455
  if (RelocInfo::IsRuntimeEntry(rmode)) {
1456
    emit(reinterpret_cast<uint32_t>(entry), rmode);
1457
  } else {
1458
    emit(entry - (pc_ + sizeof(int32_t)), rmode);
1459
  }
1460
}
1461

    
1462

    
1463
void Assembler::jmp(const Operand& adr) {
1464
  EnsureSpace ensure_space(this);
1465
  EMIT(0xFF);
1466
  emit_operand(esp, adr);
1467
}
1468

    
1469

    
1470
void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1471
  EnsureSpace ensure_space(this);
1472
  ASSERT(RelocInfo::IsCodeTarget(rmode));
1473
  EMIT(0xE9);
1474
  emit(code, rmode);
1475
}
1476

    
1477

    
1478
void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1479
  EnsureSpace ensure_space(this);
1480
  ASSERT(0 <= cc && static_cast<int>(cc) < 16);
1481
  if (L->is_bound()) {
1482
    const int short_size = 2;
1483
    const int long_size  = 6;
1484
    int offs = L->pos() - pc_offset();
1485
    ASSERT(offs <= 0);
1486
    if (is_int8(offs - short_size)) {
1487
      // 0111 tttn #8-bit disp
1488
      EMIT(0x70 | cc);
1489
      EMIT((offs - short_size) & 0xFF);
1490
    } else {
1491
      // 0000 1111 1000 tttn #32-bit disp
1492
      EMIT(0x0F);
1493
      EMIT(0x80 | cc);
1494
      emit(offs - long_size);
1495
    }
1496
  } else if (distance == Label::kNear) {
1497
    EMIT(0x70 | cc);
1498
    emit_near_disp(L);
1499
  } else {
1500
    // 0000 1111 1000 tttn #32-bit disp
1501
    // Note: could eliminate cond. jumps to this jump if condition
1502
    //       is the same however, seems to be rather unlikely case.
1503
    EMIT(0x0F);
1504
    EMIT(0x80 | cc);
1505
    emit_disp(L, Displacement::OTHER);
1506
  }
1507
}
1508

    
1509

    
1510
void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
1511
  EnsureSpace ensure_space(this);
1512
  ASSERT((0 <= cc) && (static_cast<int>(cc) < 16));
1513
  // 0000 1111 1000 tttn #32-bit disp.
1514
  EMIT(0x0F);
1515
  EMIT(0x80 | cc);
1516
  if (RelocInfo::IsRuntimeEntry(rmode)) {
1517
    emit(reinterpret_cast<uint32_t>(entry), rmode);
1518
  } else {
1519
    emit(entry - (pc_ + sizeof(int32_t)), rmode);
1520
  }
1521
}
1522

    
1523

    
1524
void Assembler::j(Condition cc, Handle<Code> code) {
1525
  EnsureSpace ensure_space(this);
1526
  // 0000 1111 1000 tttn #32-bit disp
1527
  EMIT(0x0F);
1528
  EMIT(0x80 | cc);
1529
  emit(code, RelocInfo::CODE_TARGET);
1530
}
1531

    
1532

    
1533
// FPU instructions.
1534

    
1535
void Assembler::fld(int i) {
1536
  EnsureSpace ensure_space(this);
1537
  emit_farith(0xD9, 0xC0, i);
1538
}
1539

    
1540

    
1541
void Assembler::fstp(int i) {
1542
  EnsureSpace ensure_space(this);
1543
  emit_farith(0xDD, 0xD8, i);
1544
}
1545

    
1546

    
1547
void Assembler::fld1() {
1548
  EnsureSpace ensure_space(this);
1549
  EMIT(0xD9);
1550
  EMIT(0xE8);
1551
}
1552

    
1553

    
1554
void Assembler::fldpi() {
1555
  EnsureSpace ensure_space(this);
1556
  EMIT(0xD9);
1557
  EMIT(0xEB);
1558
}
1559

    
1560

    
1561
void Assembler::fldz() {
1562
  EnsureSpace ensure_space(this);
1563
  EMIT(0xD9);
1564
  EMIT(0xEE);
1565
}
1566

    
1567

    
1568
void Assembler::fldln2() {
1569
  EnsureSpace ensure_space(this);
1570
  EMIT(0xD9);
1571
  EMIT(0xED);
1572
}
1573

    
1574

    
1575
void Assembler::fld_s(const Operand& adr) {
1576
  EnsureSpace ensure_space(this);
1577
  EMIT(0xD9);
1578
  emit_operand(eax, adr);
1579
}
1580

    
1581

    
1582
void Assembler::fld_d(const Operand& adr) {
1583
  EnsureSpace ensure_space(this);
1584
  EMIT(0xDD);
1585
  emit_operand(eax, adr);
1586
}
1587

    
1588

    
1589
void Assembler::fstp_s(const Operand& adr) {
1590
  EnsureSpace ensure_space(this);
1591
  EMIT(0xD9);
1592
  emit_operand(ebx, adr);
1593
}
1594

    
1595

    
1596
void Assembler::fst_s(const Operand& adr) {
1597
  EnsureSpace ensure_space(this);
1598
  EMIT(0xD9);
1599
  emit_operand(edx, adr);
1600
}
1601

    
1602

    
1603
void Assembler::fstp_d(const Operand& adr) {
1604
  EnsureSpace ensure_space(this);
1605
  EMIT(0xDD);
1606
  emit_operand(ebx, adr);
1607
}
1608

    
1609

    
1610
void Assembler::fst_d(const Operand& adr) {
1611
  EnsureSpace ensure_space(this);
1612
  EMIT(0xDD);
1613
  emit_operand(edx, adr);
1614
}
1615

    
1616

    
1617
void Assembler::fild_s(const Operand& adr) {
1618
  EnsureSpace ensure_space(this);
1619
  EMIT(0xDB);
1620
  emit_operand(eax, adr);
1621
}
1622

    
1623

    
1624
void Assembler::fild_d(const Operand& adr) {
1625
  EnsureSpace ensure_space(this);
1626
  EMIT(0xDF);
1627
  emit_operand(ebp, adr);
1628
}
1629

    
1630

    
1631
void Assembler::fistp_s(const Operand& adr) {
1632
  EnsureSpace ensure_space(this);
1633
  EMIT(0xDB);
1634
  emit_operand(ebx, adr);
1635
}
1636

    
1637

    
1638
void Assembler::fisttp_s(const Operand& adr) {
1639
  ASSERT(IsEnabled(SSE3));
1640
  EnsureSpace ensure_space(this);
1641
  EMIT(0xDB);
1642
  emit_operand(ecx, adr);
1643
}
1644

    
1645

    
1646
void Assembler::fisttp_d(const Operand& adr) {
1647
  ASSERT(IsEnabled(SSE3));
1648
  EnsureSpace ensure_space(this);
1649
  EMIT(0xDD);
1650
  emit_operand(ecx, adr);
1651
}
1652

    
1653

    
1654
void Assembler::fist_s(const Operand& adr) {
1655
  EnsureSpace ensure_space(this);
1656
  EMIT(0xDB);
1657
  emit_operand(edx, adr);
1658
}
1659

    
1660

    
1661
void Assembler::fistp_d(const Operand& adr) {
1662
  EnsureSpace ensure_space(this);
1663
  EMIT(0xDF);
1664
  emit_operand(edi, adr);
1665
}
1666

    
1667

    
1668
void Assembler::fabs() {
1669
  EnsureSpace ensure_space(this);
1670
  EMIT(0xD9);
1671
  EMIT(0xE1);
1672
}
1673

    
1674

    
1675
void Assembler::fchs() {
1676
  EnsureSpace ensure_space(this);
1677
  EMIT(0xD9);
1678
  EMIT(0xE0);
1679
}
1680

    
1681

    
1682
void Assembler::fcos() {
1683
  EnsureSpace ensure_space(this);
1684
  EMIT(0xD9);
1685
  EMIT(0xFF);
1686
}
1687

    
1688

    
1689
void Assembler::fsin() {
1690
  EnsureSpace ensure_space(this);
1691
  EMIT(0xD9);
1692
  EMIT(0xFE);
1693
}
1694

    
1695

    
1696
void Assembler::fptan() {
1697
  EnsureSpace ensure_space(this);
1698
  EMIT(0xD9);
1699
  EMIT(0xF2);
1700
}
1701

    
1702

    
1703
void Assembler::fyl2x() {
1704
  EnsureSpace ensure_space(this);
1705
  EMIT(0xD9);
1706
  EMIT(0xF1);
1707
}
1708

    
1709

    
1710
void Assembler::f2xm1() {
1711
  EnsureSpace ensure_space(this);
1712
  EMIT(0xD9);
1713
  EMIT(0xF0);
1714
}
1715

    
1716

    
1717
void Assembler::fscale() {
1718
  EnsureSpace ensure_space(this);
1719
  EMIT(0xD9);
1720
  EMIT(0xFD);
1721
}
1722

    
1723

    
1724
void Assembler::fninit() {
1725
  EnsureSpace ensure_space(this);
1726
  EMIT(0xDB);
1727
  EMIT(0xE3);
1728
}
1729

    
1730

    
1731
void Assembler::fadd(int i) {
1732
  EnsureSpace ensure_space(this);
1733
  emit_farith(0xDC, 0xC0, i);
1734
}
1735

    
1736

    
1737
void Assembler::fadd_i(int i) {
1738
  EnsureSpace ensure_space(this);
1739
  emit_farith(0xD8, 0xC0, i);
1740
}
1741

    
1742

    
1743
void Assembler::fsub(int i) {
1744
  EnsureSpace ensure_space(this);
1745
  emit_farith(0xDC, 0xE8, i);
1746
}
1747

    
1748

    
1749
void Assembler::fsub_i(int i) {
1750
  EnsureSpace ensure_space(this);
1751
  emit_farith(0xD8, 0xE0, i);
1752
}
1753

    
1754

    
1755
void Assembler::fisub_s(const Operand& adr) {
1756
  EnsureSpace ensure_space(this);
1757
  EMIT(0xDA);
1758
  emit_operand(esp, adr);
1759
}
1760

    
1761

    
1762
void Assembler::fmul_i(int i) {
1763
  EnsureSpace ensure_space(this);
1764
  emit_farith(0xD8, 0xC8, i);
1765
}
1766

    
1767

    
1768
void Assembler::fmul(int i) {
1769
  EnsureSpace ensure_space(this);
1770
  emit_farith(0xDC, 0xC8, i);
1771
}
1772

    
1773

    
1774
void Assembler::fdiv(int i) {
1775
  EnsureSpace ensure_space(this);
1776
  emit_farith(0xDC, 0xF8, i);
1777
}
1778

    
1779

    
1780
void Assembler::fdiv_i(int i) {
1781
  EnsureSpace ensure_space(this);
1782
  emit_farith(0xD8, 0xF0, i);
1783
}
1784

    
1785

    
1786
void Assembler::faddp(int i) {
1787
  EnsureSpace ensure_space(this);
1788
  emit_farith(0xDE, 0xC0, i);
1789
}
1790

    
1791

    
1792
void Assembler::fsubp(int i) {
1793
  EnsureSpace ensure_space(this);
1794
  emit_farith(0xDE, 0xE8, i);
1795
}
1796

    
1797

    
1798
void Assembler::fsubrp(int i) {
1799
  EnsureSpace ensure_space(this);
1800
  emit_farith(0xDE, 0xE0, i);
1801
}
1802

    
1803

    
1804
void Assembler::fmulp(int i) {
1805
  EnsureSpace ensure_space(this);
1806
  emit_farith(0xDE, 0xC8, i);
1807
}
1808

    
1809

    
1810
void Assembler::fdivp(int i) {
1811
  EnsureSpace ensure_space(this);
1812
  emit_farith(0xDE, 0xF8, i);
1813
}
1814

    
1815

    
1816
void Assembler::fprem() {
1817
  EnsureSpace ensure_space(this);
1818
  EMIT(0xD9);
1819
  EMIT(0xF8);
1820
}
1821

    
1822

    
1823
void Assembler::fprem1() {
1824
  EnsureSpace ensure_space(this);
1825
  EMIT(0xD9);
1826
  EMIT(0xF5);
1827
}
1828

    
1829

    
1830
void Assembler::fxch(int i) {
1831
  EnsureSpace ensure_space(this);
1832
  emit_farith(0xD9, 0xC8, i);
1833
}
1834

    
1835

    
1836
void Assembler::fincstp() {
1837
  EnsureSpace ensure_space(this);
1838
  EMIT(0xD9);
1839
  EMIT(0xF7);
1840
}
1841

    
1842

    
1843
void Assembler::ffree(int i) {
1844
  EnsureSpace ensure_space(this);
1845
  emit_farith(0xDD, 0xC0, i);
1846
}
1847

    
1848

    
1849
void Assembler::ftst() {
1850
  EnsureSpace ensure_space(this);
1851
  EMIT(0xD9);
1852
  EMIT(0xE4);
1853
}
1854

    
1855

    
1856
void Assembler::fucomp(int i) {
1857
  EnsureSpace ensure_space(this);
1858
  emit_farith(0xDD, 0xE8, i);
1859
}
1860

    
1861

    
1862
void Assembler::fucompp() {
1863
  EnsureSpace ensure_space(this);
1864
  EMIT(0xDA);
1865
  EMIT(0xE9);
1866
}
1867

    
1868

    
1869
void Assembler::fucomi(int i) {
1870
  EnsureSpace ensure_space(this);
1871
  EMIT(0xDB);
1872
  EMIT(0xE8 + i);
1873
}
1874

    
1875

    
1876
void Assembler::fucomip() {
1877
  EnsureSpace ensure_space(this);
1878
  EMIT(0xDF);
1879
  EMIT(0xE9);
1880
}
1881

    
1882

    
1883
void Assembler::fcompp() {
1884
  EnsureSpace ensure_space(this);
1885
  EMIT(0xDE);
1886
  EMIT(0xD9);
1887
}
1888

    
1889

    
1890
void Assembler::fnstsw_ax() {
1891
  EnsureSpace ensure_space(this);
1892
  EMIT(0xDF);
1893
  EMIT(0xE0);
1894
}
1895

    
1896

    
1897
void Assembler::fwait() {
1898
  EnsureSpace ensure_space(this);
1899
  EMIT(0x9B);
1900
}
1901

    
1902

    
1903
void Assembler::frndint() {
1904
  EnsureSpace ensure_space(this);
1905
  EMIT(0xD9);
1906
  EMIT(0xFC);
1907
}
1908

    
1909

    
1910
void Assembler::fnclex() {
1911
  EnsureSpace ensure_space(this);
1912
  EMIT(0xDB);
1913
  EMIT(0xE2);
1914
}
1915

    
1916

    
1917
void Assembler::sahf() {
1918
  EnsureSpace ensure_space(this);
1919
  EMIT(0x9E);
1920
}
1921

    
1922

    
1923
void Assembler::setcc(Condition cc, Register reg) {
1924
  ASSERT(reg.is_byte_register());
1925
  EnsureSpace ensure_space(this);
1926
  EMIT(0x0F);
1927
  EMIT(0x90 | cc);
1928
  EMIT(0xC0 | reg.code());
1929
}
1930

    
1931

    
1932
void Assembler::cvttss2si(Register dst, const Operand& src) {
1933
  ASSERT(IsEnabled(SSE2));
1934
  EnsureSpace ensure_space(this);
1935
  EMIT(0xF3);
1936
  EMIT(0x0F);
1937
  EMIT(0x2C);
1938
  emit_operand(dst, src);
1939
}
1940

    
1941

    
1942
void Assembler::cvttsd2si(Register dst, const Operand& src) {
1943
  ASSERT(IsEnabled(SSE2));
1944
  EnsureSpace ensure_space(this);
1945
  EMIT(0xF2);
1946
  EMIT(0x0F);
1947
  EMIT(0x2C);
1948
  emit_operand(dst, src);
1949
}
1950

    
1951

    
1952
void Assembler::cvtsd2si(Register dst, XMMRegister src) {
1953
  ASSERT(IsEnabled(SSE2));
1954
  EnsureSpace ensure_space(this);
1955
  EMIT(0xF2);
1956
  EMIT(0x0F);
1957
  EMIT(0x2D);
1958
  emit_sse_operand(dst, src);
1959
}
1960

    
1961

    
1962
void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
1963
  ASSERT(IsEnabled(SSE2));
1964
  EnsureSpace ensure_space(this);
1965
  EMIT(0xF2);
1966
  EMIT(0x0F);
1967
  EMIT(0x2A);
1968
  emit_sse_operand(dst, src);
1969
}
1970

    
1971

    
1972
void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
1973
  ASSERT(IsEnabled(SSE2));
1974
  EnsureSpace ensure_space(this);
1975
  EMIT(0xF3);
1976
  EMIT(0x0F);
1977
  EMIT(0x5A);
1978
  emit_sse_operand(dst, src);
1979
}
1980

    
1981

    
1982
void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
1983
  ASSERT(IsEnabled(SSE2));
1984
  EnsureSpace ensure_space(this);
1985
  EMIT(0xF2);
1986
  EMIT(0x0F);
1987
  EMIT(0x5A);
1988
  emit_sse_operand(dst, src);
1989
}
1990

    
1991

    
1992
void Assembler::addsd(XMMRegister dst, XMMRegister src) {
1993
  ASSERT(IsEnabled(SSE2));
1994
  EnsureSpace ensure_space(this);
1995
  EMIT(0xF2);
1996
  EMIT(0x0F);
1997
  EMIT(0x58);
1998
  emit_sse_operand(dst, src);
1999
}
2000

    
2001

    
2002
void Assembler::addsd(XMMRegister dst, const Operand& src) {
2003
  ASSERT(IsEnabled(SSE2));
2004
  EnsureSpace ensure_space(this);
2005
  EMIT(0xF2);
2006
  EMIT(0x0F);
2007
  EMIT(0x58);
2008
  emit_sse_operand(dst, src);
2009
}
2010

    
2011

    
2012
void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
2013
  ASSERT(IsEnabled(SSE2));
2014
  EnsureSpace ensure_space(this);
2015
  EMIT(0xF2);
2016
  EMIT(0x0F);
2017
  EMIT(0x59);
2018
  emit_sse_operand(dst, src);
2019
}
2020

    
2021

    
2022
void Assembler::mulsd(XMMRegister dst, const Operand& src) {
2023
  ASSERT(IsEnabled(SSE2));
2024
  EnsureSpace ensure_space(this);
2025
  EMIT(0xF2);
2026
  EMIT(0x0F);
2027
  EMIT(0x59);
2028
  emit_sse_operand(dst, src);
2029
}
2030

    
2031

    
2032
void Assembler::subsd(XMMRegister dst, XMMRegister src) {
2033
  ASSERT(IsEnabled(SSE2));
2034
  EnsureSpace ensure_space(this);
2035
  EMIT(0xF2);
2036
  EMIT(0x0F);
2037
  EMIT(0x5C);
2038
  emit_sse_operand(dst, src);
2039
}
2040

    
2041

    
2042
void Assembler::divsd(XMMRegister dst, XMMRegister src) {
2043
  ASSERT(IsEnabled(SSE2));
2044
  EnsureSpace ensure_space(this);
2045
  EMIT(0xF2);
2046
  EMIT(0x0F);
2047
  EMIT(0x5E);
2048
  emit_sse_operand(dst, src);
2049
}
2050

    
2051

    
2052
void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
2053
  ASSERT(IsEnabled(SSE2));
2054
  EnsureSpace ensure_space(this);
2055
  EMIT(0x66);
2056
  EMIT(0x0F);
2057
  EMIT(0x57);
2058
  emit_sse_operand(dst, src);
2059
}
2060

    
2061

    
2062
void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2063
  EnsureSpace ensure_space(this);
2064
  EMIT(0x0F);
2065
  EMIT(0x57);
2066
  emit_sse_operand(dst, src);
2067
}
2068

    
2069

    
2070
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2071
  ASSERT(IsEnabled(SSE2));
2072
  EnsureSpace ensure_space(this);
2073
  EMIT(0xF2);
2074
  EMIT(0x0F);
2075
  EMIT(0x51);
2076
  emit_sse_operand(dst, src);
2077
}
2078

    
2079

    
2080
void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2081
  ASSERT(IsEnabled(SSE2));
2082
  EnsureSpace ensure_space(this);
2083
  EMIT(0x66);
2084
  EMIT(0x0F);
2085
  EMIT(0x54);
2086
  emit_sse_operand(dst, src);
2087
}
2088

    
2089

    
2090
void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2091
  ASSERT(IsEnabled(SSE2));
2092
  EnsureSpace ensure_space(this);
2093
  EMIT(0x66);
2094
  EMIT(0x0F);
2095
  EMIT(0x56);
2096
  emit_sse_operand(dst, src);
2097
}
2098

    
2099

    
2100
void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
2101
  ASSERT(IsEnabled(SSE2));
2102
  EnsureSpace ensure_space(this);
2103
  EMIT(0x66);
2104
  EMIT(0x0F);
2105
  EMIT(0x2E);
2106
  emit_sse_operand(dst, src);
2107
}
2108

    
2109

    
2110
void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
2111
  ASSERT(IsEnabled(SSE2));
2112
  EnsureSpace ensure_space(this);
2113
  EMIT(0x66);
2114
  EMIT(0x0F);
2115
  EMIT(0x2E);
2116
  emit_sse_operand(dst, src);
2117
}
2118

    
2119

    
2120
void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2121
  ASSERT(IsEnabled(SSE4_1));
2122
  EnsureSpace ensure_space(this);
2123
  EMIT(0x66);
2124
  EMIT(0x0F);
2125
  EMIT(0x3A);
2126
  EMIT(0x0B);
2127
  emit_sse_operand(dst, src);
2128
  // Mask precision exeption.
2129
  EMIT(static_cast<byte>(mode) | 0x8);
2130
}
2131

    
2132

    
2133
void Assembler::movmskpd(Register dst, XMMRegister src) {
2134
  ASSERT(IsEnabled(SSE2));
2135
  EnsureSpace ensure_space(this);
2136
  EMIT(0x66);
2137
  EMIT(0x0F);
2138
  EMIT(0x50);
2139
  emit_sse_operand(dst, src);
2140
}
2141

    
2142

    
2143
void Assembler::movmskps(Register dst, XMMRegister src) {
2144
  ASSERT(IsEnabled(SSE2));
2145
  EnsureSpace ensure_space(this);
2146
  EMIT(0x0F);
2147
  EMIT(0x50);
2148
  emit_sse_operand(dst, src);
2149
}
2150

    
2151

    
2152
void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
2153
  ASSERT(IsEnabled(SSE2));
2154
  EnsureSpace ensure_space(this);
2155
  EMIT(0x66);
2156
  EMIT(0x0F);
2157
  EMIT(0x76);
2158
  emit_sse_operand(dst, src);
2159
}
2160

    
2161

    
2162
void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
2163
  ASSERT(IsEnabled(SSE2));
2164
  EnsureSpace ensure_space(this);
2165
  EMIT(0xF2);
2166
  EMIT(0x0F);
2167
  EMIT(0xC2);
2168
  emit_sse_operand(dst, src);
2169
  EMIT(1);  // LT == 1
2170
}
2171

    
2172

    
2173
void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2174
  ASSERT(IsEnabled(SSE2));
2175
  EnsureSpace ensure_space(this);
2176
  EMIT(0x0F);
2177
  EMIT(0x28);
2178
  emit_sse_operand(dst, src);
2179
}
2180

    
2181

    
2182
void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2183
  ASSERT(IsEnabled(SSE2));
2184
  EnsureSpace ensure_space(this);
2185
  EMIT(0x66);
2186
  EMIT(0x0F);
2187
  EMIT(0x7F);
2188
  emit_sse_operand(src, dst);
2189
}
2190

    
2191

    
2192
void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2193
  ASSERT(IsEnabled(SSE2));
2194
  EnsureSpace ensure_space(this);
2195
  EMIT(0x66);
2196
  EMIT(0x0F);
2197
  EMIT(0x6F);
2198
  emit_sse_operand(dst, src);
2199
}
2200

    
2201

    
2202
void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
2203
  ASSERT(IsEnabled(SSE2));
2204
  EnsureSpace ensure_space(this);
2205
  EMIT(0xF3);
2206
  EMIT(0x0F);
2207
  EMIT(0x7F);
2208
  emit_sse_operand(src, dst);
2209
}
2210

    
2211

    
2212
void Assembler::movdqu(XMMRegister dst, const Operand& src) {
2213
  ASSERT(IsEnabled(SSE2));
2214
  EnsureSpace ensure_space(this);
2215
  EMIT(0xF3);
2216
  EMIT(0x0F);
2217
  EMIT(0x6F);
2218
  emit_sse_operand(dst, src);
2219
}
2220

    
2221

    
2222
void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
2223
  ASSERT(IsEnabled(SSE4_1));
2224
  EnsureSpace ensure_space(this);
2225
  EMIT(0x66);
2226
  EMIT(0x0F);
2227
  EMIT(0x38);
2228
  EMIT(0x2A);
2229
  emit_sse_operand(dst, src);
2230
}
2231

    
2232

    
2233
void Assembler::movntdq(const Operand& dst, XMMRegister src) {
2234
  ASSERT(IsEnabled(SSE2));
2235
  EnsureSpace ensure_space(this);
2236
  EMIT(0x66);
2237
  EMIT(0x0F);
2238
  EMIT(0xE7);
2239
  emit_sse_operand(src, dst);
2240
}
2241

    
2242

    
2243
void Assembler::prefetch(const Operand& src, int level) {
2244
  ASSERT(is_uint2(level));
2245
  EnsureSpace ensure_space(this);
2246
  EMIT(0x0F);
2247
  EMIT(0x18);
2248
  // Emit hint number in Reg position of RegR/M.
2249
  XMMRegister code = XMMRegister::from_code(level);
2250
  emit_sse_operand(code, src);
2251
}
2252

    
2253

    
2254
void Assembler::movsd(const Operand& dst, XMMRegister src ) {
2255
  ASSERT(IsEnabled(SSE2));
2256
  EnsureSpace ensure_space(this);
2257
  EMIT(0xF2);  // double
2258
  EMIT(0x0F);
2259
  EMIT(0x11);  // store
2260
  emit_sse_operand(src, dst);
2261
}
2262

    
2263

    
2264
void Assembler::movsd(XMMRegister dst, const Operand& src) {
2265
  ASSERT(IsEnabled(SSE2));
2266
  EnsureSpace ensure_space(this);
2267
  EMIT(0xF2);  // double
2268
  EMIT(0x0F);
2269
  EMIT(0x10);  // load
2270
  emit_sse_operand(dst, src);
2271
}
2272

    
2273

    
2274
void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2275
  ASSERT(IsEnabled(SSE2));
2276
  EnsureSpace ensure_space(this);
2277
  EMIT(0xF2);
2278
  EMIT(0x0F);
2279
  EMIT(0x10);
2280
  emit_sse_operand(dst, src);
2281
}
2282

    
2283

    
2284
void Assembler::movss(const Operand& dst, XMMRegister src ) {
2285
  ASSERT(IsEnabled(SSE2));
2286
  EnsureSpace ensure_space(this);
2287
  EMIT(0xF3);  // float
2288
  EMIT(0x0F);
2289
  EMIT(0x11);  // store
2290
  emit_sse_operand(src, dst);
2291
}
2292

    
2293

    
2294
void Assembler::movss(XMMRegister dst, const Operand& src) {
2295
  ASSERT(IsEnabled(SSE2));
2296
  EnsureSpace ensure_space(this);
2297
  EMIT(0xF3);  // float
2298
  EMIT(0x0F);
2299
  EMIT(0x10);  // load
2300
  emit_sse_operand(dst, src);
2301
}
2302

    
2303

    
2304
void Assembler::movss(XMMRegister dst, XMMRegister src) {
2305
  ASSERT(IsEnabled(SSE2));
2306
  EnsureSpace ensure_space(this);
2307
  EMIT(0xF3);
2308
  EMIT(0x0F);
2309
  EMIT(0x10);
2310
  emit_sse_operand(dst, src);
2311
}
2312

    
2313

    
2314
void Assembler::movd(XMMRegister dst, const Operand& src) {
2315
  ASSERT(IsEnabled(SSE2));
2316
  EnsureSpace ensure_space(this);
2317
  EMIT(0x66);
2318
  EMIT(0x0F);
2319
  EMIT(0x6E);
2320
  emit_sse_operand(dst, src);
2321
}
2322

    
2323

    
2324
void Assembler::movd(const Operand& dst, XMMRegister src) {
2325
  ASSERT(IsEnabled(SSE2));
2326
  EnsureSpace ensure_space(this);
2327
  EMIT(0x66);
2328
  EMIT(0x0F);
2329
  EMIT(0x7E);
2330
  emit_sse_operand(src, dst);
2331
}
2332

    
2333

    
2334
void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2335
  ASSERT(IsEnabled(SSE4_1));
2336
  ASSERT(is_uint8(imm8));
2337
  EnsureSpace ensure_space(this);
2338
  EMIT(0x66);
2339
  EMIT(0x0F);
2340
  EMIT(0x3A);
2341
  EMIT(0x17);
2342
  emit_sse_operand(src, dst);
2343
  EMIT(imm8);
2344
}
2345

    
2346

    
2347
void Assembler::andps(XMMRegister dst, XMMRegister src) {
2348
  EnsureSpace ensure_space(this);
2349
  EMIT(0x0F);
2350
  EMIT(0x54);
2351
  emit_sse_operand(dst, src);
2352
}
2353

    
2354

    
2355
void Assembler::pand(XMMRegister dst, XMMRegister src) {
2356
  ASSERT(IsEnabled(SSE2));
2357
  EnsureSpace ensure_space(this);
2358
  EMIT(0x66);
2359
  EMIT(0x0F);
2360
  EMIT(0xDB);
2361
  emit_sse_operand(dst, src);
2362
}
2363

    
2364

    
2365
void Assembler::pxor(XMMRegister dst, XMMRegister src) {
2366
  ASSERT(IsEnabled(SSE2));
2367
  EnsureSpace ensure_space(this);
2368
  EMIT(0x66);
2369
  EMIT(0x0F);
2370
  EMIT(0xEF);
2371
  emit_sse_operand(dst, src);
2372
}
2373

    
2374

    
2375
void Assembler::por(XMMRegister dst, XMMRegister src) {
2376
  ASSERT(IsEnabled(SSE2));
2377
  EnsureSpace ensure_space(this);
2378
  EMIT(0x66);
2379
  EMIT(0x0F);
2380
  EMIT(0xEB);
2381
  emit_sse_operand(dst, src);
2382
}
2383

    
2384

    
2385
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
2386
  ASSERT(IsEnabled(SSE4_1));
2387
  EnsureSpace ensure_space(this);
2388
  EMIT(0x66);
2389
  EMIT(0x0F);
2390
  EMIT(0x38);
2391
  EMIT(0x17);
2392
  emit_sse_operand(dst, src);
2393
}
2394

    
2395

    
2396
void Assembler::psllq(XMMRegister reg, int8_t shift) {
2397
  ASSERT(IsEnabled(SSE2));
2398
  EnsureSpace ensure_space(this);
2399
  EMIT(0x66);
2400
  EMIT(0x0F);
2401
  EMIT(0x73);
2402
  emit_sse_operand(esi, reg);  // esi == 6
2403
  EMIT(shift);
2404
}
2405

    
2406

    
2407
void Assembler::psllq(XMMRegister dst, XMMRegister src) {
2408
  ASSERT(IsEnabled(SSE2));
2409
  EnsureSpace ensure_space(this);
2410
  EMIT(0x66);
2411
  EMIT(0x0F);
2412
  EMIT(0xF3);
2413
  emit_sse_operand(dst, src);
2414
}
2415

    
2416

    
2417
void Assembler::psrlq(XMMRegister reg, int8_t shift) {
2418
  ASSERT(IsEnabled(SSE2));
2419
  EnsureSpace ensure_space(this);
2420
  EMIT(0x66);
2421
  EMIT(0x0F);
2422
  EMIT(0x73);
2423
  emit_sse_operand(edx, reg);  // edx == 2
2424
  EMIT(shift);
2425
}
2426

    
2427

    
2428
void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
2429
  ASSERT(IsEnabled(SSE2));
2430
  EnsureSpace ensure_space(this);
2431
  EMIT(0x66);
2432
  EMIT(0x0F);
2433
  EMIT(0xD3);
2434
  emit_sse_operand(dst, src);
2435
}
2436

    
2437

    
2438
void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
2439
  ASSERT(IsEnabled(SSE2));
2440
  EnsureSpace ensure_space(this);
2441
  EMIT(0x66);
2442
  EMIT(0x0F);
2443
  EMIT(0x70);
2444
  emit_sse_operand(dst, src);
2445
  EMIT(shuffle);
2446
}
2447

    
2448

    
2449
void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
2450
  ASSERT(IsEnabled(SSE4_1));
2451
  EnsureSpace ensure_space(this);
2452
  EMIT(0x66);
2453
  EMIT(0x0F);
2454
  EMIT(0x3A);
2455
  EMIT(0x16);
2456
  emit_sse_operand(src, dst);
2457
  EMIT(offset);
2458
}
2459

    
2460

    
2461
void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
2462
  ASSERT(IsEnabled(SSE4_1));
2463
  EnsureSpace ensure_space(this);
2464
  EMIT(0x66);
2465
  EMIT(0x0F);
2466
  EMIT(0x3A);
2467
  EMIT(0x22);
2468
  emit_sse_operand(dst, src);
2469
  EMIT(offset);
2470
}
2471

    
2472

    
2473
void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2474
  Register ireg = { reg.code() };
2475
  emit_operand(ireg, adr);
2476
}
2477

    
2478

    
2479
void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2480
  EMIT(0xC0 | dst.code() << 3 | src.code());
2481
}
2482

    
2483

    
2484
void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2485
  EMIT(0xC0 | dst.code() << 3 | src.code());
2486
}
2487

    
2488

    
2489
void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2490
  EMIT(0xC0 | (dst.code() << 3) | src.code());
2491
}
2492

    
2493

    
2494
void Assembler::Print() {
2495
  Disassembler::Decode(isolate(), stdout, buffer_, pc_);
2496
}
2497

    
2498

    
2499
void Assembler::RecordJSReturn() {
2500
  positions_recorder()->WriteRecordedPositions();
2501
  EnsureSpace ensure_space(this);
2502
  RecordRelocInfo(RelocInfo::JS_RETURN);
2503
}
2504

    
2505

    
2506
void Assembler::RecordDebugBreakSlot() {
2507
  positions_recorder()->WriteRecordedPositions();
2508
  EnsureSpace ensure_space(this);
2509
  RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2510
}
2511

    
2512

    
2513
void Assembler::RecordComment(const char* msg, bool force) {
2514
  if (FLAG_code_comments || force) {
2515
    EnsureSpace ensure_space(this);
2516
    RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2517
  }
2518
}
2519

    
2520

    
2521
void Assembler::GrowBuffer() {
2522
  ASSERT(overflow());
2523
  if (!own_buffer_) FATAL("external code buffer is too small");
2524

    
2525
  // Compute new buffer size.
2526
  CodeDesc desc;  // the new buffer
2527
  if (buffer_size_ < 4*KB) {
2528
    desc.buffer_size = 4*KB;
2529
  } else {
2530
    desc.buffer_size = 2*buffer_size_;
2531
  }
2532
  // Some internal data structures overflow for very large buffers,
2533
  // they must ensure that kMaximalBufferSize is not too large.
2534
  if ((desc.buffer_size > kMaximalBufferSize) ||
2535
      (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
2536
    V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2537
  }
2538

    
2539
  // Set up new buffer.
2540
  desc.buffer = NewArray<byte>(desc.buffer_size);
2541
  desc.instr_size = pc_offset();
2542
  desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2543

    
2544
  // Clear the buffer in debug mode. Use 'int3' instructions to make
2545
  // sure to get into problems if we ever run uninitialized code.
2546
#ifdef DEBUG
2547
  memset(desc.buffer, 0xCC, desc.buffer_size);
2548
#endif
2549

    
2550
  // Copy the data.
2551
  int pc_delta = desc.buffer - buffer_;
2552
  int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2553
  OS::MemMove(desc.buffer, buffer_, desc.instr_size);
2554
  OS::MemMove(rc_delta + reloc_info_writer.pos(),
2555
              reloc_info_writer.pos(), desc.reloc_size);
2556

    
2557
  // Switch buffers.
2558
  if (isolate()->assembler_spare_buffer() == NULL &&
2559
      buffer_size_ == kMinimalBufferSize) {
2560
    isolate()->set_assembler_spare_buffer(buffer_);
2561
  } else {
2562
    DeleteArray(buffer_);
2563
  }
2564
  buffer_ = desc.buffer;
2565
  buffer_size_ = desc.buffer_size;
2566
  pc_ += pc_delta;
2567
  reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2568
                               reloc_info_writer.last_pc() + pc_delta);
2569

    
2570
  // Relocate runtime entries.
2571
  for (RelocIterator it(desc); !it.done(); it.next()) {
2572
    RelocInfo::Mode rmode = it.rinfo()->rmode();
2573
    if (rmode == RelocInfo::INTERNAL_REFERENCE) {
2574
      int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2575
      if (*p != 0) {  // 0 means uninitialized.
2576
        *p += pc_delta;
2577
      }
2578
    }
2579
  }
2580

    
2581
  ASSERT(!overflow());
2582
}
2583

    
2584

    
2585
void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
2586
  ASSERT(is_uint8(op1) && is_uint8(op2));  // wrong opcode
2587
  ASSERT(is_uint8(imm8));
2588
  ASSERT((op1 & 0x01) == 0);  // should be 8bit operation
2589
  EMIT(op1);
2590
  EMIT(op2 | dst.code());
2591
  EMIT(imm8);
2592
}
2593

    
2594

    
2595
void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
2596
  ASSERT((0 <= sel) && (sel <= 7));
2597
  Register ireg = { sel };
2598
  if (x.is_int8()) {
2599
    EMIT(0x83);  // using a sign-extended 8-bit immediate.
2600
    emit_operand(ireg, dst);
2601
    EMIT(x.x_ & 0xFF);
2602
  } else if (dst.is_reg(eax)) {
2603
    EMIT((sel << 3) | 0x05);  // short form if the destination is eax.
2604
    emit(x);
2605
  } else {
2606
    EMIT(0x81);  // using a literal 32-bit immediate.
2607
    emit_operand(ireg, dst);
2608
    emit(x);
2609
  }
2610
}
2611

    
2612

    
2613
void Assembler::emit_operand(Register reg, const Operand& adr) {
2614
  const unsigned length = adr.len_;
2615
  ASSERT(length > 0);
2616

    
2617
  // Emit updated ModRM byte containing the given register.
2618
  pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2619

    
2620
  // Emit the rest of the encoded operand.
2621
  for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2622
  pc_ += length;
2623

    
2624
  // Emit relocation information if necessary.
2625
  if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
2626
    pc_ -= sizeof(int32_t);  // pc_ must be *at* disp32
2627
    RecordRelocInfo(adr.rmode_);
2628
    pc_ += sizeof(int32_t);
2629
  }
2630
}
2631

    
2632

    
2633
void Assembler::emit_farith(int b1, int b2, int i) {
2634
  ASSERT(is_uint8(b1) && is_uint8(b2));  // wrong opcode
2635
  ASSERT(0 <= i &&  i < 8);  // illegal stack offset
2636
  EMIT(b1);
2637
  EMIT(b2 + i);
2638
}
2639

    
2640

    
2641
void Assembler::db(uint8_t data) {
2642
  EnsureSpace ensure_space(this);
2643
  EMIT(data);
2644
}
2645

    
2646

    
2647
void Assembler::dd(uint32_t data) {
2648
  EnsureSpace ensure_space(this);
2649
  emit(data);
2650
}
2651

    
2652

    
2653
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2654
  ASSERT(!RelocInfo::IsNone(rmode));
2655
  // Don't record external references unless the heap will be serialized.
2656
  if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2657
#ifdef DEBUG
2658
    if (!Serializer::enabled()) {
2659
      Serializer::TooLateToEnableNow();
2660
    }
2661
#endif
2662
    if (!Serializer::enabled() && !emit_debug_code()) {
2663
      return;
2664
    }
2665
  }
2666
  RelocInfo rinfo(pc_, rmode, data, NULL);
2667
  reloc_info_writer.Write(&rinfo);
2668
}
2669

    
2670

    
2671
#ifdef GENERATED_CODE_COVERAGE
2672
static FILE* coverage_log = NULL;
2673

    
2674

    
2675
static void InitCoverageLog() {
2676
  char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
2677
  if (file_name != NULL) {
2678
    coverage_log = fopen(file_name, "aw+");
2679
  }
2680
}
2681

    
2682

    
2683
void LogGeneratedCodeCoverage(const char* file_line) {
2684
  const char* return_address = (&file_line)[-1];
2685
  char* push_insn = const_cast<char*>(return_address - 12);
2686
  push_insn[0] = 0xeb;  // Relative branch insn.
2687
  push_insn[1] = 13;    // Skip over coverage insns.
2688
  if (coverage_log != NULL) {
2689
    fprintf(coverage_log, "%s\n", file_line);
2690
    fflush(coverage_log);
2691
  }
2692
}
2693

    
2694
#endif
2695

    
2696
} }  // namespace v8::internal
2697

    
2698
#endif  // V8_TARGET_ARCH_IA32