blob: 7b32f1b1de1c97ec7dbfdeb79ec11c1f2f2a4bba [file] [log] [blame]
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001// 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.
yangguo@chromium.org56454712012-02-16 15:33:53 +000035// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036
37#include "v8.h"
38
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +000039#if defined(V8_TARGET_ARCH_IA32)
40
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000041#include "disassembler.h"
42#include "macro-assembler.h"
43#include "serialize.h"
44
kasperl@chromium.org71affb52009-05-26 05:44:31 +000045namespace v8 {
46namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000047
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048// -----------------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049// Implementation of CpuFeatures
50
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +000051#ifdef DEBUG
52bool CpuFeatures::initialized_ = false;
53#endif
54uint64_t CpuFeatures::supported_ = 0;
ulan@chromium.org750145a2013-03-07 15:14:13 +000055uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000056
57
yangguo@chromium.org003650e2013-01-24 16:31:08 +000058ExternalReference ExternalReference::cpu_features() {
59 ASSERT(CpuFeatures::initialized_);
60 return ExternalReference(&CpuFeatures::supported_);
61}
62
63
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000064int IntelDoubleRegister::NumAllocatableRegisters() {
65 if (CpuFeatures::IsSupported(SSE2)) {
66 return XMMRegister::kNumAllocatableRegisters;
67 } else {
68 return X87TopOfStackRegister::kNumAllocatableRegisters;
69 }
70}
71
72
73int IntelDoubleRegister::NumRegisters() {
74 if (CpuFeatures::IsSupported(SSE2)) {
75 return XMMRegister::kNumRegisters;
76 } else {
77 return X87TopOfStackRegister::kNumRegisters;
78 }
79}
80
81
82const char* IntelDoubleRegister::AllocationIndexToString(int index) {
83 if (CpuFeatures::IsSupported(SSE2)) {
84 return XMMRegister::AllocationIndexToString(index);
85 } else {
86 return X87TopOfStackRegister::AllocationIndexToString(index);
87 }
88}
89
90
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000091// The Probe method needs executable memory, so it uses Heap::CreateCode.
92// Allocation failure is silent and leads to safe default.
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +000093void CpuFeatures::Probe() {
94 ASSERT(!initialized_);
kasperl@chromium.org061ef742009-02-27 12:16:20 +000095 ASSERT(supported_ == 0);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +000096#ifdef DEBUG
97 initialized_ = true;
98#endif
99 if (Serializer::enabled()) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000100 supported_ |= OS::CpuFeaturesImpliedByPlatform();
101 return; // No features if we might serialize.
102 }
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000103
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000104 const int kBufferSize = 4 * KB;
105 VirtualMemory* memory = new VirtualMemory(kBufferSize);
106 if (!memory->IsReserved()) {
107 delete memory;
108 return;
109 }
110 ASSERT(memory->size() >= static_cast<size_t>(kBufferSize));
111 if (!memory->Commit(memory->address(), kBufferSize, true/*executable*/)) {
112 delete memory;
113 return;
114 }
115
116 Assembler assm(NULL, memory->address(), kBufferSize);
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000117 Label cpuid, done;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000118#define __ assm.
119 // Save old esp, since we are going to modify the stack.
120 __ push(ebp);
121 __ pushfd();
122 __ push(ecx);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123 __ push(ebx);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000124 __ mov(ebp, esp);
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000125
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000126 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported.
127 __ pushfd();
128 __ pop(eax);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000129 __ mov(edx, eax);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000130 __ xor_(eax, 0x200000); // Flip bit 21.
131 __ push(eax);
132 __ popfd();
133 __ pushfd();
134 __ pop(eax);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000135 __ xor_(eax, edx); // Different if CPUID is supported.
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000136 __ j(not_zero, &cpuid);
137
138 // CPUID not supported. Clear the supported features in edx:eax.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000139 __ xor_(eax, eax);
140 __ xor_(edx, edx);
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000141 __ jmp(&done);
142
143 // Invoke CPUID with 1 in eax to get feature information in
144 // ecx:edx. Temporarily enable CPUID support because we know it's
145 // safe here.
146 __ bind(&cpuid);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000147 __ mov(eax, 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000148 supported_ = (1 << CPUID);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000149 { CpuFeatureScope fscope(&assm, CPUID);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000150 __ cpuid();
151 }
152 supported_ = 0;
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000153
154 // Move the result from ecx:edx to edx:eax and make sure to mark the
155 // CPUID feature as supported.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000156 __ mov(eax, edx);
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000157 __ or_(eax, 1 << CPUID);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000158 __ mov(edx, ecx);
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000159
160 // Done.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000161 __ bind(&done);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000162 __ mov(esp, ebp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000163 __ pop(ebx);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000164 __ pop(ecx);
165 __ popfd();
166 __ pop(ebp);
167 __ ret(0);
168#undef __
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000169
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000170 typedef uint64_t (*F0)();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000171 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address()));
ulan@chromium.org750145a2013-03-07 15:14:13 +0000172 uint64_t probed_features = probe();
173 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform();
174 supported_ = probed_features | platform_features;
175 found_by_runtime_probing_only_ = probed_features & ~platform_features;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000176
177 delete memory;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000178}
179
180
181// -----------------------------------------------------------------------------
kasper.lund7276f142008-07-30 08:49:36 +0000182// Implementation of Displacement
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000183
kasper.lund7276f142008-07-30 08:49:36 +0000184void Displacement::init(Label* L, Type type) {
185 ASSERT(!L->is_bound());
186 int next = 0;
187 if (L->is_linked()) {
188 next = L->pos();
189 ASSERT(next > 0); // Displacements must be at positions > 0
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000190 }
kasper.lund7276f142008-07-30 08:49:36 +0000191 // Ensure that we _never_ overflow the next field.
192 ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize));
193 data_ = NextField::encode(next) | TypeField::encode(type);
194}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000195
196
197// -----------------------------------------------------------------------------
198// Implementation of RelocInfo
199
200
201const int RelocInfo::kApplyMask =
ager@chromium.org236ad962008-09-25 09:45:57 +0000202 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000203 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000204 1 << RelocInfo::DEBUG_BREAK_SLOT | 1 << RelocInfo::CODE_AGE_SEQUENCE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205
206
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000207bool RelocInfo::IsCodedSpecially() {
208 // The deserializer needs to know whether a pointer is specially coded. Being
209 // specially coded on IA32 means that it is a relative address, as used by
210 // branch instructions. These are also the ones that need changing when a
211 // code object moves.
212 return (1 << rmode_) & kApplyMask;
213}
214
215
iposva@chromium.org245aa852009-02-10 00:49:54 +0000216void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217 // Patch the code at the current address with the supplied instructions.
218 for (int i = 0; i < instruction_count; i++) {
219 *(pc_ + i) = *(instructions + i);
220 }
ager@chromium.org4af710e2009-09-15 12:20:11 +0000221
222 // Indicate that code has changed.
223 CPU::FlushICache(pc_, instruction_count);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224}
225
226
227// Patch the code at the current PC with a call to the target address.
228// Additional guard int3 instructions can be added if required.
iposva@chromium.org245aa852009-02-10 00:49:54 +0000229void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000230 // Call instruction takes up 5 bytes and int3 takes up one byte.
ager@chromium.org4af710e2009-09-15 12:20:11 +0000231 static const int kCallCodeSize = 5;
232 int code_size = kCallCodeSize + guard_bytes;
233
234 // Create a code patcher.
235 CodePatcher patcher(pc_, code_size);
236
237 // Add a label for checking the size of the code used for returning.
238#ifdef DEBUG
239 Label check_codesize;
240 patcher.masm()->bind(&check_codesize);
241#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000242
243 // Patch the code.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000244 patcher.masm()->call(target, RelocInfo::NONE32);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000245
ager@chromium.org4af710e2009-09-15 12:20:11 +0000246 // Check that the size of the code generated is as expected.
247 ASSERT_EQ(kCallCodeSize,
248 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
249
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250 // Add the requested number of int3 instructions after the call.
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000251 ASSERT_GE(guard_bytes, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000252 for (int i = 0; i < guard_bytes; i++) {
253 patcher.masm()->int3();
254 }
255}
256
257
258// -----------------------------------------------------------------------------
259// Implementation of Operand
260
ager@chromium.org236ad962008-09-25 09:45:57 +0000261Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000262 // [base + disp/r]
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000263 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000264 // [base]
265 set_modrm(0, base);
266 if (base.is(esp)) set_sib(times_1, esp, base);
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000267 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268 // [base + disp8]
269 set_modrm(1, base);
270 if (base.is(esp)) set_sib(times_1, esp, base);
271 set_disp8(disp);
272 } else {
273 // [base + disp/r]
274 set_modrm(2, base);
275 if (base.is(esp)) set_sib(times_1, esp, base);
276 set_dispr(disp, rmode);
277 }
278}
279
280
281Operand::Operand(Register base,
282 Register index,
283 ScaleFactor scale,
284 int32_t disp,
ager@chromium.org236ad962008-09-25 09:45:57 +0000285 RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000286 ASSERT(!index.is(esp)); // illegal addressing mode
287 // [base + index*scale + disp/r]
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000288 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000289 // [base + index*scale]
290 set_modrm(0, esp);
291 set_sib(scale, index, base);
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000292 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000293 // [base + index*scale + disp8]
294 set_modrm(1, esp);
295 set_sib(scale, index, base);
296 set_disp8(disp);
297 } else {
298 // [base + index*scale + disp/r]
299 set_modrm(2, esp);
300 set_sib(scale, index, base);
301 set_dispr(disp, rmode);
302 }
303}
304
305
306Operand::Operand(Register index,
307 ScaleFactor scale,
308 int32_t disp,
ager@chromium.org236ad962008-09-25 09:45:57 +0000309 RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000310 ASSERT(!index.is(esp)); // illegal addressing mode
311 // [index*scale + disp/r]
312 set_modrm(0, esp);
313 set_sib(scale, index, ebp);
314 set_dispr(disp, rmode);
315}
316
317
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000318bool Operand::is_reg(Register reg) const {
319 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only.
320 && ((buf_[0] & 0x07) == reg.code()); // register codes match.
321}
322
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000323
324bool Operand::is_reg_only() const {
325 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only.
326}
327
328
329Register Operand::reg() const {
330 ASSERT(is_reg_only());
331 return Register::from_code(buf_[0] & 0x07);
332}
333
334
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000335// -----------------------------------------------------------------------------
ager@chromium.org5c838252010-02-19 08:53:10 +0000336// Implementation of Assembler.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000337
338// Emit a single byte. Must always be inlined.
339#define EMIT(x) \
340 *pc_++ = (x)
341
342
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000343#ifdef GENERATED_CODE_COVERAGE
344static void InitCoverageLog();
345#endif
346
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000347Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
348 : AssemblerBase(isolate, buffer, buffer_size),
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000349 positions_recorder_(this) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000350 // Clear the buffer in debug mode unless it was provided by the
351 // caller in which case we can't be sure it's okay to overwrite
352 // existing code in it; see CodePatcher::CodePatcher(...).
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000353#ifdef DEBUG
354 if (own_buffer_) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000355 memset(buffer_, 0xCC, buffer_size_); // int3
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000356 }
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000357#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000358
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000359 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000360
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000361#ifdef GENERATED_CODE_COVERAGE
362 InitCoverageLog();
363#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000364}
365
366
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000367void Assembler::GetCode(CodeDesc* desc) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000368 // Finalize code (at this point overflow() may be true, but the gap ensures
369 // that we are still not overlapping instructions and relocation info).
370 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000371 // Set up code descriptor.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000372 desc->buffer = buffer_;
373 desc->buffer_size = buffer_size_;
374 desc->instr_size = pc_offset();
375 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000376 desc->origin = this;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000377}
378
379
380void Assembler::Align(int m) {
381 ASSERT(IsPowerOf2(m));
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000382 int mask = m - 1;
383 int addr = pc_offset();
384 Nop((m - (addr & mask)) & mask);
385}
386
387
388bool Assembler::IsNop(Address addr) {
389 Address a = addr;
390 while (*a == 0x66) a++;
391 if (*a == 0x90) return true;
392 if (a[0] == 0xf && a[1] == 0x1f) return true;
393 return false;
394}
395
396
397void Assembler::Nop(int bytes) {
398 EnsureSpace ensure_space(this);
399
400 if (!CpuFeatures::IsSupported(SSE2)) {
401 // Older CPUs that do not support SSE2 may not support multibyte NOP
402 // instructions.
403 for (; bytes > 0; bytes--) {
404 EMIT(0x90);
405 }
406 return;
407 }
408
409 // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
410 while (bytes > 0) {
411 switch (bytes) {
412 case 2:
413 EMIT(0x66);
414 case 1:
415 EMIT(0x90);
416 return;
417 case 3:
418 EMIT(0xf);
419 EMIT(0x1f);
420 EMIT(0);
421 return;
422 case 4:
423 EMIT(0xf);
424 EMIT(0x1f);
425 EMIT(0x40);
426 EMIT(0);
427 return;
428 case 6:
429 EMIT(0x66);
430 case 5:
431 EMIT(0xf);
432 EMIT(0x1f);
433 EMIT(0x44);
434 EMIT(0);
435 EMIT(0);
436 return;
437 case 7:
438 EMIT(0xf);
439 EMIT(0x1f);
440 EMIT(0x80);
441 EMIT(0);
442 EMIT(0);
443 EMIT(0);
444 EMIT(0);
445 return;
446 default:
447 case 11:
448 EMIT(0x66);
449 bytes--;
450 case 10:
451 EMIT(0x66);
452 bytes--;
453 case 9:
454 EMIT(0x66);
455 bytes--;
456 case 8:
457 EMIT(0xf);
458 EMIT(0x1f);
459 EMIT(0x84);
460 EMIT(0);
461 EMIT(0);
462 EMIT(0);
463 EMIT(0);
464 EMIT(0);
465 bytes -= 8;
466 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 }
468}
469
470
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000471void Assembler::CodeTargetAlign() {
472 Align(16); // Preferred alignment of jump targets on ia32.
473}
474
475
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476void Assembler::cpuid() {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000477 ASSERT(IsEnabled(CPUID));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000478 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 EMIT(0x0F);
480 EMIT(0xA2);
481}
482
483
484void Assembler::pushad() {
485 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000486 EMIT(0x60);
487}
488
489
490void Assembler::popad() {
491 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000492 EMIT(0x61);
493}
494
495
496void Assembler::pushfd() {
497 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498 EMIT(0x9C);
499}
500
501
502void Assembler::popfd() {
503 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000504 EMIT(0x9D);
505}
506
507
508void Assembler::push(const Immediate& x) {
509 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000510 if (x.is_int8()) {
511 EMIT(0x6a);
512 EMIT(x.x_);
513 } else {
514 EMIT(0x68);
515 emit(x);
516 }
517}
518
519
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000520void Assembler::push_imm32(int32_t imm32) {
521 EnsureSpace ensure_space(this);
522 EMIT(0x68);
523 emit(imm32);
524}
525
526
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000527void Assembler::push(Register src) {
528 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000529 EMIT(0x50 | src.code());
530}
531
532
533void Assembler::push(const Operand& src) {
534 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000535 EMIT(0xFF);
536 emit_operand(esi, src);
537}
538
539
540void Assembler::pop(Register dst) {
541 ASSERT(reloc_info_writer.last_pc() != NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000543 EMIT(0x58 | dst.code());
544}
545
546
547void Assembler::pop(const Operand& dst) {
548 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000549 EMIT(0x8F);
550 emit_operand(eax, dst);
551}
552
553
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000554void Assembler::enter(const Immediate& size) {
555 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000556 EMIT(0xC8);
557 emit_w(size);
558 EMIT(0);
559}
560
561
562void Assembler::leave() {
563 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000564 EMIT(0xC9);
565}
566
567
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568void Assembler::mov_b(Register dst, const Operand& src) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000569 CHECK(dst.is_byte_register());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000570 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000571 EMIT(0x8A);
572 emit_operand(dst, src);
573}
574
575
576void Assembler::mov_b(const Operand& dst, int8_t imm8) {
577 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000578 EMIT(0xC6);
579 emit_operand(eax, dst);
580 EMIT(imm8);
581}
582
583
584void Assembler::mov_b(const Operand& dst, Register src) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000585 CHECK(src.is_byte_register());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587 EMIT(0x88);
588 emit_operand(src, dst);
589}
590
591
592void Assembler::mov_w(Register dst, const Operand& src) {
593 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594 EMIT(0x66);
595 EMIT(0x8B);
596 emit_operand(dst, src);
597}
598
599
600void Assembler::mov_w(const Operand& dst, Register src) {
601 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000602 EMIT(0x66);
603 EMIT(0x89);
604 emit_operand(src, dst);
605}
606
607
608void Assembler::mov(Register dst, int32_t imm32) {
609 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000610 EMIT(0xB8 | dst.code());
611 emit(imm32);
612}
613
614
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000615void Assembler::mov(Register dst, const Immediate& x) {
616 EnsureSpace ensure_space(this);
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000617 EMIT(0xB8 | dst.code());
618 emit(x);
619}
620
621
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000622void Assembler::mov(Register dst, Handle<Object> handle) {
623 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000624 EMIT(0xB8 | dst.code());
625 emit(handle);
626}
627
628
629void Assembler::mov(Register dst, const Operand& src) {
630 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000631 EMIT(0x8B);
632 emit_operand(dst, src);
633}
634
635
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000636void Assembler::mov(Register dst, Register src) {
637 EnsureSpace ensure_space(this);
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000638 EMIT(0x89);
639 EMIT(0xC0 | src.code() << 3 | dst.code());
640}
641
642
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000643void Assembler::mov(const Operand& dst, const Immediate& x) {
644 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645 EMIT(0xC7);
646 emit_operand(eax, dst);
647 emit(x);
648}
649
650
651void Assembler::mov(const Operand& dst, Handle<Object> handle) {
652 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000653 EMIT(0xC7);
654 emit_operand(eax, dst);
655 emit(handle);
656}
657
658
659void Assembler::mov(const Operand& dst, Register src) {
660 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000661 EMIT(0x89);
662 emit_operand(src, dst);
663}
664
665
666void Assembler::movsx_b(Register dst, const Operand& src) {
667 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000668 EMIT(0x0F);
669 EMIT(0xBE);
670 emit_operand(dst, src);
671}
672
673
674void Assembler::movsx_w(Register dst, const Operand& src) {
675 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000676 EMIT(0x0F);
677 EMIT(0xBF);
678 emit_operand(dst, src);
679}
680
681
682void Assembler::movzx_b(Register dst, const Operand& src) {
683 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684 EMIT(0x0F);
685 EMIT(0xB6);
686 emit_operand(dst, src);
687}
688
689
690void Assembler::movzx_w(Register dst, const Operand& src) {
691 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000692 EMIT(0x0F);
693 EMIT(0xB7);
694 emit_operand(dst, src);
695}
696
697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698void Assembler::cmov(Condition cc, Register dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000699 ASSERT(IsEnabled(CMOV));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000700 EnsureSpace ensure_space(this);
ager@chromium.org5c838252010-02-19 08:53:10 +0000701 // Opcode: 0f 40 + cc /r.
ager@chromium.org4af710e2009-09-15 12:20:11 +0000702 EMIT(0x0F);
703 EMIT(0x40 + cc);
704 emit_operand(dst, src);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000705}
706
707
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000708void Assembler::cld() {
709 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000710 EMIT(0xFC);
711}
712
713
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000714void Assembler::rep_movs() {
715 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000716 EMIT(0xF3);
717 EMIT(0xA5);
718}
719
720
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000721void Assembler::rep_stos() {
722 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000723 EMIT(0xF3);
724 EMIT(0xAB);
725}
726
727
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000728void Assembler::stos() {
729 EnsureSpace ensure_space(this);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000730 EMIT(0xAB);
731}
732
733
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000734void Assembler::xchg(Register dst, Register src) {
735 EnsureSpace ensure_space(this);
ager@chromium.org5c838252010-02-19 08:53:10 +0000736 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding.
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000737 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
738 } else {
739 EMIT(0x87);
740 EMIT(0xC0 | src.code() << 3 | dst.code());
741 }
742}
743
744
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745void Assembler::adc(Register dst, int32_t imm32) {
746 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000747 emit_arith(2, Operand(dst), Immediate(imm32));
748}
749
750
751void Assembler::adc(Register dst, const Operand& src) {
752 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000753 EMIT(0x13);
754 emit_operand(dst, src);
755}
756
757
758void Assembler::add(Register dst, const Operand& src) {
759 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760 EMIT(0x03);
761 emit_operand(dst, src);
762}
763
764
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000765void Assembler::add(const Operand& dst, Register src) {
766 EnsureSpace ensure_space(this);
767 EMIT(0x01);
768 emit_operand(src, dst);
769}
770
771
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772void Assembler::add(const Operand& dst, const Immediate& x) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000773 ASSERT(reloc_info_writer.last_pc() != NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000774 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000775 emit_arith(0, dst, x);
776}
777
778
779void Assembler::and_(Register dst, int32_t imm32) {
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +0000780 and_(dst, Immediate(imm32));
781}
782
783
784void Assembler::and_(Register dst, const Immediate& x) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000785 EnsureSpace ensure_space(this);
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +0000786 emit_arith(4, Operand(dst), x);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
790void Assembler::and_(Register dst, const Operand& src) {
791 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792 EMIT(0x23);
793 emit_operand(dst, src);
794}
795
796
797void Assembler::and_(const Operand& dst, const Immediate& x) {
798 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000799 emit_arith(4, dst, x);
800}
801
802
803void Assembler::and_(const Operand& dst, Register src) {
804 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000805 EMIT(0x21);
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000806 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000807}
808
809
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000810void Assembler::cmpb(const Operand& op, int8_t imm8) {
811 EnsureSpace ensure_space(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000812 if (op.is_reg(eax)) {
813 EMIT(0x3C);
814 } else {
815 EMIT(0x80);
816 emit_operand(edi, op); // edi == 7
817 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000818 EMIT(imm8);
819}
820
821
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000822void Assembler::cmpb(const Operand& op, Register reg) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000823 CHECK(reg.is_byte_register());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000824 EnsureSpace ensure_space(this);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000825 EMIT(0x38);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000826 emit_operand(reg, op);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000827}
828
829
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000830void Assembler::cmpb(Register reg, const Operand& op) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000831 CHECK(reg.is_byte_register());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000832 EnsureSpace ensure_space(this);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000833 EMIT(0x3A);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000834 emit_operand(reg, op);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000835}
836
837
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000838void Assembler::cmpw(const Operand& op, Immediate imm16) {
839 ASSERT(imm16.is_int16());
840 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000841 EMIT(0x66);
842 EMIT(0x81);
843 emit_operand(edi, op);
844 emit_w(imm16);
845}
846
847
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000848void Assembler::cmp(Register reg, int32_t imm32) {
849 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850 emit_arith(7, Operand(reg), Immediate(imm32));
851}
852
853
854void Assembler::cmp(Register reg, Handle<Object> handle) {
855 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000856 emit_arith(7, Operand(reg), Immediate(handle));
857}
858
859
860void Assembler::cmp(Register reg, const Operand& op) {
861 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000862 EMIT(0x3B);
863 emit_operand(reg, op);
864}
865
866
867void Assembler::cmp(const Operand& op, const Immediate& imm) {
868 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000869 emit_arith(7, op, imm);
870}
871
872
ager@chromium.org4af710e2009-09-15 12:20:11 +0000873void Assembler::cmp(const Operand& op, Handle<Object> handle) {
874 EnsureSpace ensure_space(this);
ager@chromium.org4af710e2009-09-15 12:20:11 +0000875 emit_arith(7, op, Immediate(handle));
876}
877
878
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000879void Assembler::cmpb_al(const Operand& op) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000880 EnsureSpace ensure_space(this);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000881 EMIT(0x38); // CMP r/m8, r8
882 emit_operand(eax, op); // eax has same code as register al.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000883}
884
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000885
886void Assembler::cmpw_ax(const Operand& op) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000887 EnsureSpace ensure_space(this);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000888 EMIT(0x66);
889 EMIT(0x39); // CMP r/m16, r16
890 emit_operand(eax, op); // eax has same code as register ax.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000891}
892
893
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000894void Assembler::dec_b(Register dst) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000895 CHECK(dst.is_byte_register());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000896 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000897 EMIT(0xFE);
898 EMIT(0xC8 | dst.code());
899}
900
901
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000902void Assembler::dec_b(const Operand& dst) {
903 EnsureSpace ensure_space(this);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000904 EMIT(0xFE);
905 emit_operand(ecx, dst);
906}
907
908
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000909void Assembler::dec(Register dst) {
910 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000911 EMIT(0x48 | dst.code());
912}
913
914
915void Assembler::dec(const Operand& dst) {
916 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000917 EMIT(0xFF);
918 emit_operand(ecx, dst);
919}
920
921
922void Assembler::cdq() {
923 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000924 EMIT(0x99);
925}
926
927
928void Assembler::idiv(Register src) {
929 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930 EMIT(0xF7);
931 EMIT(0xF8 | src.code());
932}
933
934
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000935void Assembler::imul(Register reg) {
936 EnsureSpace ensure_space(this);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000937 EMIT(0xF7);
938 EMIT(0xE8 | reg.code());
939}
940
941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942void Assembler::imul(Register dst, const Operand& src) {
943 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000944 EMIT(0x0F);
945 EMIT(0xAF);
946 emit_operand(dst, src);
947}
948
949
950void Assembler::imul(Register dst, Register src, int32_t imm32) {
951 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000952 if (is_int8(imm32)) {
953 EMIT(0x6B);
954 EMIT(0xC0 | dst.code() << 3 | src.code());
955 EMIT(imm32);
956 } else {
957 EMIT(0x69);
958 EMIT(0xC0 | dst.code() << 3 | src.code());
959 emit(imm32);
960 }
961}
962
963
964void Assembler::inc(Register dst) {
965 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000966 EMIT(0x40 | dst.code());
967}
968
969
970void Assembler::inc(const Operand& dst) {
971 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000972 EMIT(0xFF);
973 emit_operand(eax, dst);
974}
975
976
977void Assembler::lea(Register dst, const Operand& src) {
978 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000979 EMIT(0x8D);
980 emit_operand(dst, src);
981}
982
983
984void Assembler::mul(Register src) {
985 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986 EMIT(0xF7);
987 EMIT(0xE0 | src.code());
988}
989
990
991void Assembler::neg(Register dst) {
992 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993 EMIT(0xF7);
994 EMIT(0xD8 | dst.code());
995}
996
997
998void Assembler::not_(Register dst) {
999 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001000 EMIT(0xF7);
1001 EMIT(0xD0 | dst.code());
1002}
1003
1004
1005void Assembler::or_(Register dst, int32_t imm32) {
1006 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001007 emit_arith(1, Operand(dst), Immediate(imm32));
1008}
1009
1010
1011void Assembler::or_(Register dst, const Operand& src) {
1012 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001013 EMIT(0x0B);
1014 emit_operand(dst, src);
1015}
1016
1017
1018void Assembler::or_(const Operand& dst, const Immediate& x) {
1019 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020 emit_arith(1, dst, x);
1021}
1022
1023
1024void Assembler::or_(const Operand& dst, Register src) {
1025 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001026 EMIT(0x09);
ager@chromium.org3bf7b912008-11-17 09:09:45 +00001027 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001028}
1029
1030
1031void Assembler::rcl(Register dst, uint8_t imm8) {
1032 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001033 ASSERT(is_uint5(imm8)); // illegal shift count
1034 if (imm8 == 1) {
1035 EMIT(0xD1);
1036 EMIT(0xD0 | dst.code());
1037 } else {
1038 EMIT(0xC1);
1039 EMIT(0xD0 | dst.code());
1040 EMIT(imm8);
1041 }
1042}
1043
1044
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00001045void Assembler::rcr(Register dst, uint8_t imm8) {
1046 EnsureSpace ensure_space(this);
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00001047 ASSERT(is_uint5(imm8)); // illegal shift count
1048 if (imm8 == 1) {
1049 EMIT(0xD1);
1050 EMIT(0xD8 | dst.code());
1051 } else {
1052 EMIT(0xC1);
1053 EMIT(0xD8 | dst.code());
1054 EMIT(imm8);
1055 }
1056}
1057
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00001058void Assembler::ror(Register dst, uint8_t imm8) {
1059 EnsureSpace ensure_space(this);
1060 ASSERT(is_uint5(imm8)); // illegal shift count
1061 if (imm8 == 1) {
1062 EMIT(0xD1);
1063 EMIT(0xC8 | dst.code());
1064 } else {
1065 EMIT(0xC1);
1066 EMIT(0xC8 | dst.code());
1067 EMIT(imm8);
1068 }
1069}
1070
1071void Assembler::ror_cl(Register dst) {
1072 EnsureSpace ensure_space(this);
1073 EMIT(0xD3);
1074 EMIT(0xC8 | dst.code());
1075}
1076
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00001077
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001078void Assembler::sar(Register dst, uint8_t imm8) {
1079 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001080 ASSERT(is_uint5(imm8)); // illegal shift count
1081 if (imm8 == 1) {
1082 EMIT(0xD1);
1083 EMIT(0xF8 | dst.code());
1084 } else {
1085 EMIT(0xC1);
1086 EMIT(0xF8 | dst.code());
1087 EMIT(imm8);
1088 }
1089}
1090
1091
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001092void Assembler::sar_cl(Register dst) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001093 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001094 EMIT(0xD3);
1095 EMIT(0xF8 | dst.code());
1096}
1097
1098
1099void Assembler::sbb(Register dst, const Operand& src) {
1100 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001101 EMIT(0x1B);
1102 emit_operand(dst, src);
1103}
1104
1105
1106void Assembler::shld(Register dst, const Operand& src) {
1107 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001108 EMIT(0x0F);
1109 EMIT(0xA5);
1110 emit_operand(dst, src);
1111}
1112
1113
1114void Assembler::shl(Register dst, uint8_t imm8) {
1115 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001116 ASSERT(is_uint5(imm8)); // illegal shift count
1117 if (imm8 == 1) {
1118 EMIT(0xD1);
1119 EMIT(0xE0 | dst.code());
1120 } else {
1121 EMIT(0xC1);
1122 EMIT(0xE0 | dst.code());
1123 EMIT(imm8);
1124 }
1125}
1126
1127
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001128void Assembler::shl_cl(Register dst) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001129 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001130 EMIT(0xD3);
1131 EMIT(0xE0 | dst.code());
1132}
1133
1134
1135void Assembler::shrd(Register dst, const Operand& src) {
1136 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001137 EMIT(0x0F);
1138 EMIT(0xAD);
1139 emit_operand(dst, src);
1140}
1141
1142
1143void Assembler::shr(Register dst, uint8_t imm8) {
1144 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001145 ASSERT(is_uint5(imm8)); // illegal shift count
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001146 if (imm8 == 1) {
1147 EMIT(0xD1);
1148 EMIT(0xE8 | dst.code());
1149 } else {
1150 EMIT(0xC1);
1151 EMIT(0xE8 | dst.code());
1152 EMIT(imm8);
1153 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001154}
1155
1156
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001157void Assembler::shr_cl(Register dst) {
1158 EnsureSpace ensure_space(this);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001159 EMIT(0xD3);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001160 EMIT(0xE8 | dst.code());
1161}
1162
1163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164void Assembler::sub(const Operand& dst, const Immediate& x) {
1165 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001166 emit_arith(5, dst, x);
1167}
1168
1169
1170void Assembler::sub(Register dst, const Operand& src) {
1171 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001172 EMIT(0x2B);
1173 emit_operand(dst, src);
1174}
1175
1176
1177void Assembler::sub(const Operand& dst, Register src) {
1178 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001179 EMIT(0x29);
ager@chromium.org3bf7b912008-11-17 09:09:45 +00001180 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001181}
1182
1183
1184void Assembler::test(Register reg, const Immediate& imm) {
1185 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001186 // Only use test against byte for registers that have a byte
1187 // variant: eax, ebx, ecx, and edx.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001188 if (RelocInfo::IsNone(imm.rmode_) &&
yangguo@chromium.org56454712012-02-16 15:33:53 +00001189 is_uint8(imm.x_) &&
1190 reg.is_byte_register()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001191 uint8_t imm8 = imm.x_;
1192 if (reg.is(eax)) {
1193 EMIT(0xA8);
1194 EMIT(imm8);
1195 } else {
1196 emit_arith_b(0xF6, 0xC0, reg, imm8);
1197 }
1198 } else {
1199 // This is not using emit_arith because test doesn't support
1200 // sign-extension of 8-bit operands.
1201 if (reg.is(eax)) {
1202 EMIT(0xA9);
1203 } else {
1204 EMIT(0xF7);
1205 EMIT(0xC0 | reg.code());
1206 }
1207 emit(imm);
1208 }
1209}
1210
1211
1212void Assembler::test(Register reg, const Operand& op) {
1213 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001214 EMIT(0x85);
1215 emit_operand(reg, op);
1216}
1217
1218
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001219void Assembler::test_b(Register reg, const Operand& op) {
yangguo@chromium.org56454712012-02-16 15:33:53 +00001220 CHECK(reg.is_byte_register());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001221 EnsureSpace ensure_space(this);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001222 EMIT(0x84);
1223 emit_operand(reg, op);
1224}
1225
1226
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001227void Assembler::test(const Operand& op, const Immediate& imm) {
1228 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001229 EMIT(0xF7);
1230 emit_operand(eax, op);
1231 emit(imm);
1232}
1233
1234
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001235void Assembler::test_b(const Operand& op, uint8_t imm8) {
yangguo@chromium.org56454712012-02-16 15:33:53 +00001236 if (op.is_reg_only() && !op.reg().is_byte_register()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001237 test(op, Immediate(imm8));
1238 return;
1239 }
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001240 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001241 EMIT(0xF6);
1242 emit_operand(eax, op);
1243 EMIT(imm8);
1244}
1245
1246
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001247void Assembler::xor_(Register dst, int32_t imm32) {
1248 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001249 emit_arith(6, Operand(dst), Immediate(imm32));
1250}
1251
1252
1253void Assembler::xor_(Register dst, const Operand& src) {
1254 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001255 EMIT(0x33);
1256 emit_operand(dst, src);
1257}
1258
1259
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001260void Assembler::xor_(const Operand& dst, Register src) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001261 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001262 EMIT(0x31);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001263 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001264}
1265
1266
1267void Assembler::xor_(const Operand& dst, const Immediate& x) {
1268 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269 emit_arith(6, dst, x);
1270}
1271
1272
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001273void Assembler::bt(const Operand& dst, Register src) {
1274 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001275 EMIT(0x0F);
1276 EMIT(0xA3);
1277 emit_operand(src, dst);
1278}
1279
1280
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001281void Assembler::bts(const Operand& dst, Register src) {
1282 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001283 EMIT(0x0F);
1284 EMIT(0xAB);
1285 emit_operand(src, dst);
1286}
1287
1288
1289void Assembler::hlt() {
1290 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001291 EMIT(0xF4);
1292}
1293
1294
1295void Assembler::int3() {
1296 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001297 EMIT(0xCC);
1298}
1299
1300
1301void Assembler::nop() {
1302 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001303 EMIT(0x90);
1304}
1305
1306
1307void Assembler::rdtsc() {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001308 ASSERT(IsEnabled(RDTSC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001309 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001310 EMIT(0x0F);
1311 EMIT(0x31);
1312}
1313
1314
1315void Assembler::ret(int imm16) {
1316 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001317 ASSERT(is_uint16(imm16));
1318 if (imm16 == 0) {
1319 EMIT(0xC3);
1320 } else {
1321 EMIT(0xC2);
1322 EMIT(imm16 & 0xFF);
1323 EMIT((imm16 >> 8) & 0xFF);
1324 }
1325}
1326
1327
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001328// Labels refer to positions in the (to be) generated code.
1329// There are bound, linked, and unused labels.
1330//
1331// Bound labels refer to known positions in the already
1332// generated code. pos() is the position the label refers to.
1333//
1334// Linked labels refer to unknown positions in the code
1335// to be generated; pos() is the position of the 32bit
1336// Displacement of the last instruction using the label.
1337
1338
1339void Assembler::print(Label* L) {
1340 if (L->is_unused()) {
1341 PrintF("unused label\n");
1342 } else if (L->is_bound()) {
1343 PrintF("bound label to %d\n", L->pos());
1344 } else if (L->is_linked()) {
1345 Label l = *L;
1346 PrintF("unbound label");
1347 while (l.is_linked()) {
1348 Displacement disp = disp_at(&l);
1349 PrintF("@ %d ", l.pos());
1350 disp.print();
1351 PrintF("\n");
1352 disp.next(&l);
1353 }
1354 } else {
1355 PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1356 }
1357}
1358
1359
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001360void Assembler::bind_to(Label* L, int pos) {
1361 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001362 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position
1363 while (L->is_linked()) {
1364 Displacement disp = disp_at(L);
1365 int fixup_pos = L->pos();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001366 if (disp.type() == Displacement::CODE_RELATIVE) {
1367 // Relative to Code* heap object pointer.
1368 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1369 } else {
1370 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1371 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
1372 }
ager@chromium.org5c838252010-02-19 08:53:10 +00001373 // Relative address, relative to point after address.
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001374 int imm32 = pos - (fixup_pos + sizeof(int32_t));
1375 long_at_put(fixup_pos, imm32);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001376 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001377 disp.next(L);
1378 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001379 while (L->is_near_linked()) {
1380 int fixup_pos = L->near_link_pos();
1381 int offset_to_next =
1382 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
1383 ASSERT(offset_to_next <= 0);
1384 // Relative address, relative to point after address.
1385 int disp = pos - fixup_pos - sizeof(int8_t);
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00001386 CHECK(0 <= disp && disp <= 127);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001387 set_byte_at(fixup_pos, disp);
1388 if (offset_to_next < 0) {
1389 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1390 } else {
1391 L->UnuseNear();
1392 }
1393 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001394 L->bind_to(pos);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001395}
1396
1397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001398void Assembler::bind(Label* L) {
1399 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400 ASSERT(!L->is_bound()); // label can only be bound once
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001401 bind_to(L, pc_offset());
1402}
1403
1404
1405void Assembler::call(Label* L) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001406 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408 if (L->is_bound()) {
1409 const int long_size = 5;
1410 int offs = L->pos() - pc_offset();
1411 ASSERT(offs <= 0);
ager@chromium.org5c838252010-02-19 08:53:10 +00001412 // 1110 1000 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001413 EMIT(0xE8);
1414 emit(offs - long_size);
1415 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001416 // 1110 1000 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417 EMIT(0xE8);
1418 emit_disp(L, Displacement::OTHER);
1419 }
1420}
1421
1422
ager@chromium.org236ad962008-09-25 09:45:57 +00001423void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001425 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001426 ASSERT(!RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001427 EMIT(0xE8);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001428 if (RelocInfo::IsRuntimeEntry(rmode)) {
1429 emit(reinterpret_cast<uint32_t>(entry), rmode);
1430 } else {
1431 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1432 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001433}
1434
1435
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001436int Assembler::CallSize(const Operand& adr) {
1437 // Call size is 1 (opcode) + adr.len_ (operand).
1438 return 1 + adr.len_;
1439}
1440
1441
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442void Assembler::call(const Operand& adr) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001443 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001444 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001445 EMIT(0xFF);
1446 emit_operand(edx, adr);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001447}
1448
1449
1450int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1451 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001452}
1453
1454
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001455void Assembler::call(Handle<Code> code,
1456 RelocInfo::Mode rmode,
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001457 TypeFeedbackId ast_id) {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00001458 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001460 ASSERT(RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001461 EMIT(0xE8);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001462 emit(code, rmode, ast_id);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001463}
1464
1465
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001466void Assembler::jmp(Label* L, Label::Distance distance) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001467 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468 if (L->is_bound()) {
1469 const int short_size = 2;
1470 const int long_size = 5;
1471 int offs = L->pos() - pc_offset();
1472 ASSERT(offs <= 0);
1473 if (is_int8(offs - short_size)) {
ager@chromium.org5c838252010-02-19 08:53:10 +00001474 // 1110 1011 #8-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001475 EMIT(0xEB);
1476 EMIT((offs - short_size) & 0xFF);
1477 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001478 // 1110 1001 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001479 EMIT(0xE9);
1480 emit(offs - long_size);
1481 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001482 } else if (distance == Label::kNear) {
1483 EMIT(0xEB);
1484 emit_near_disp(L);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001485 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001486 // 1110 1001 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001487 EMIT(0xE9);
1488 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1489 }
1490}
1491
1492
ager@chromium.org236ad962008-09-25 09:45:57 +00001493void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001495 ASSERT(!RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001496 EMIT(0xE9);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001497 if (RelocInfo::IsRuntimeEntry(rmode)) {
1498 emit(reinterpret_cast<uint32_t>(entry), rmode);
1499 } else {
1500 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1501 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001502}
1503
1504
1505void Assembler::jmp(const Operand& adr) {
1506 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001507 EMIT(0xFF);
1508 emit_operand(esp, adr);
1509}
1510
1511
ager@chromium.org236ad962008-09-25 09:45:57 +00001512void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001513 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001514 ASSERT(RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001515 EMIT(0xE9);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001516 emit(code, rmode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001517}
1518
1519
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001520void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001521 EnsureSpace ensure_space(this);
danno@chromium.org72204d52012-10-31 10:02:10 +00001522 ASSERT(0 <= cc && static_cast<int>(cc) < 16);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001523 if (L->is_bound()) {
1524 const int short_size = 2;
1525 const int long_size = 6;
1526 int offs = L->pos() - pc_offset();
1527 ASSERT(offs <= 0);
1528 if (is_int8(offs - short_size)) {
1529 // 0111 tttn #8-bit disp
1530 EMIT(0x70 | cc);
1531 EMIT((offs - short_size) & 0xFF);
1532 } else {
1533 // 0000 1111 1000 tttn #32-bit disp
1534 EMIT(0x0F);
1535 EMIT(0x80 | cc);
1536 emit(offs - long_size);
1537 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001538 } else if (distance == Label::kNear) {
1539 EMIT(0x70 | cc);
1540 emit_near_disp(L);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001541 } else {
1542 // 0000 1111 1000 tttn #32-bit disp
1543 // Note: could eliminate cond. jumps to this jump if condition
1544 // is the same however, seems to be rather unlikely case.
1545 EMIT(0x0F);
1546 EMIT(0x80 | cc);
1547 emit_disp(L, Displacement::OTHER);
1548 }
1549}
1550
1551
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001552void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001553 EnsureSpace ensure_space(this);
danno@chromium.org72204d52012-10-31 10:02:10 +00001554 ASSERT((0 <= cc) && (static_cast<int>(cc) < 16));
ager@chromium.org5c838252010-02-19 08:53:10 +00001555 // 0000 1111 1000 tttn #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001556 EMIT(0x0F);
1557 EMIT(0x80 | cc);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001558 if (RelocInfo::IsRuntimeEntry(rmode)) {
1559 emit(reinterpret_cast<uint32_t>(entry), rmode);
1560 } else {
1561 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1562 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001563}
1564
1565
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001566void Assembler::j(Condition cc, Handle<Code> code) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001567 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001568 // 0000 1111 1000 tttn #32-bit disp
1569 EMIT(0x0F);
1570 EMIT(0x80 | cc);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001571 emit(code, RelocInfo::CODE_TARGET);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001572}
1573
1574
ager@chromium.org5c838252010-02-19 08:53:10 +00001575// FPU instructions.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001576
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001577void Assembler::fld(int i) {
1578 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001579 emit_farith(0xD9, 0xC0, i);
1580}
1581
1582
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001583void Assembler::fstp(int i) {
1584 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001585 emit_farith(0xDD, 0xD8, i);
1586}
1587
1588
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001589void Assembler::fld1() {
1590 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001591 EMIT(0xD9);
1592 EMIT(0xE8);
1593}
1594
1595
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001596void Assembler::fldpi() {
1597 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001598 EMIT(0xD9);
1599 EMIT(0xEB);
1600}
1601
1602
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001603void Assembler::fldz() {
1604 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605 EMIT(0xD9);
1606 EMIT(0xEE);
1607}
1608
1609
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001610void Assembler::fldln2() {
1611 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001612 EMIT(0xD9);
1613 EMIT(0xED);
1614}
1615
1616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617void Assembler::fld_s(const Operand& adr) {
1618 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619 EMIT(0xD9);
1620 emit_operand(eax, adr);
1621}
1622
1623
1624void Assembler::fld_d(const Operand& adr) {
1625 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001626 EMIT(0xDD);
1627 emit_operand(eax, adr);
1628}
1629
1630
1631void Assembler::fstp_s(const Operand& adr) {
1632 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001633 EMIT(0xD9);
1634 emit_operand(ebx, adr);
1635}
1636
1637
1638void Assembler::fstp_d(const Operand& adr) {
1639 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001640 EMIT(0xDD);
1641 emit_operand(ebx, adr);
1642}
1643
1644
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001645void Assembler::fst_d(const Operand& adr) {
1646 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001647 EMIT(0xDD);
1648 emit_operand(edx, adr);
1649}
1650
1651
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001652void Assembler::fild_s(const Operand& adr) {
1653 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001654 EMIT(0xDB);
1655 emit_operand(eax, adr);
1656}
1657
1658
1659void Assembler::fild_d(const Operand& adr) {
1660 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001661 EMIT(0xDF);
1662 emit_operand(ebp, adr);
1663}
1664
1665
1666void Assembler::fistp_s(const Operand& adr) {
1667 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001668 EMIT(0xDB);
1669 emit_operand(ebx, adr);
1670}
1671
1672
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001673void Assembler::fisttp_s(const Operand& adr) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001674 ASSERT(IsEnabled(SSE3));
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001675 EnsureSpace ensure_space(this);
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001676 EMIT(0xDB);
1677 emit_operand(ecx, adr);
1678}
1679
1680
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001681void Assembler::fisttp_d(const Operand& adr) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001682 ASSERT(IsEnabled(SSE3));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001683 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001684 EMIT(0xDD);
1685 emit_operand(ecx, adr);
1686}
1687
1688
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001689void Assembler::fist_s(const Operand& adr) {
1690 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001691 EMIT(0xDB);
1692 emit_operand(edx, adr);
1693}
1694
1695
1696void Assembler::fistp_d(const Operand& adr) {
1697 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001698 EMIT(0xDF);
1699 emit_operand(edi, adr);
1700}
1701
1702
1703void Assembler::fabs() {
1704 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705 EMIT(0xD9);
1706 EMIT(0xE1);
1707}
1708
1709
1710void Assembler::fchs() {
1711 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001712 EMIT(0xD9);
1713 EMIT(0xE0);
1714}
1715
1716
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001717void Assembler::fcos() {
1718 EnsureSpace ensure_space(this);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001719 EMIT(0xD9);
1720 EMIT(0xFF);
1721}
1722
1723
1724void Assembler::fsin() {
1725 EnsureSpace ensure_space(this);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001726 EMIT(0xD9);
1727 EMIT(0xFE);
1728}
1729
1730
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001731void Assembler::fptan() {
1732 EnsureSpace ensure_space(this);
1733 EMIT(0xD9);
1734 EMIT(0xF2);
1735}
1736
1737
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001738void Assembler::fyl2x() {
1739 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001740 EMIT(0xD9);
1741 EMIT(0xF1);
1742}
1743
1744
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001745void Assembler::f2xm1() {
1746 EnsureSpace ensure_space(this);
1747 EMIT(0xD9);
1748 EMIT(0xF0);
1749}
1750
1751
1752void Assembler::fscale() {
1753 EnsureSpace ensure_space(this);
1754 EMIT(0xD9);
1755 EMIT(0xFD);
1756}
1757
1758
1759void Assembler::fninit() {
1760 EnsureSpace ensure_space(this);
1761 EMIT(0xDB);
1762 EMIT(0xE3);
1763}
1764
1765
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001766void Assembler::fadd(int i) {
1767 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001768 emit_farith(0xDC, 0xC0, i);
1769}
1770
1771
1772void Assembler::fsub(int i) {
1773 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001774 emit_farith(0xDC, 0xE8, i);
1775}
1776
1777
1778void Assembler::fisub_s(const Operand& adr) {
1779 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001780 EMIT(0xDA);
1781 emit_operand(esp, adr);
1782}
1783
1784
1785void Assembler::fmul(int i) {
1786 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 emit_farith(0xDC, 0xC8, i);
1788}
1789
1790
1791void Assembler::fdiv(int i) {
1792 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001793 emit_farith(0xDC, 0xF8, i);
1794}
1795
1796
1797void Assembler::faddp(int i) {
1798 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 emit_farith(0xDE, 0xC0, i);
1800}
1801
1802
1803void Assembler::fsubp(int i) {
1804 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805 emit_farith(0xDE, 0xE8, i);
1806}
1807
1808
1809void Assembler::fsubrp(int i) {
1810 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001811 emit_farith(0xDE, 0xE0, i);
1812}
1813
1814
1815void Assembler::fmulp(int i) {
1816 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817 emit_farith(0xDE, 0xC8, i);
1818}
1819
1820
1821void Assembler::fdivp(int i) {
1822 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001823 emit_farith(0xDE, 0xF8, i);
1824}
1825
1826
1827void Assembler::fprem() {
1828 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829 EMIT(0xD9);
1830 EMIT(0xF8);
1831}
1832
1833
1834void Assembler::fprem1() {
1835 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001836 EMIT(0xD9);
1837 EMIT(0xF5);
1838}
1839
1840
1841void Assembler::fxch(int i) {
1842 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001843 emit_farith(0xD9, 0xC8, i);
1844}
1845
1846
1847void Assembler::fincstp() {
1848 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849 EMIT(0xD9);
1850 EMIT(0xF7);
1851}
1852
1853
1854void Assembler::ffree(int i) {
1855 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856 emit_farith(0xDD, 0xC0, i);
1857}
1858
1859
1860void Assembler::ftst() {
1861 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001862 EMIT(0xD9);
1863 EMIT(0xE4);
1864}
1865
1866
1867void Assembler::fucomp(int i) {
1868 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001869 emit_farith(0xDD, 0xE8, i);
1870}
1871
1872
1873void Assembler::fucompp() {
1874 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001875 EMIT(0xDA);
1876 EMIT(0xE9);
1877}
1878
1879
ager@chromium.org3811b432009-10-28 14:53:37 +00001880void Assembler::fucomi(int i) {
1881 EnsureSpace ensure_space(this);
ager@chromium.org3811b432009-10-28 14:53:37 +00001882 EMIT(0xDB);
1883 EMIT(0xE8 + i);
1884}
1885
1886
1887void Assembler::fucomip() {
1888 EnsureSpace ensure_space(this);
ager@chromium.org3811b432009-10-28 14:53:37 +00001889 EMIT(0xDF);
1890 EMIT(0xE9);
1891}
1892
1893
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894void Assembler::fcompp() {
1895 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001896 EMIT(0xDE);
1897 EMIT(0xD9);
1898}
1899
1900
1901void Assembler::fnstsw_ax() {
1902 EnsureSpace ensure_space(this);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001903 EMIT(0xDF);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904 EMIT(0xE0);
1905}
1906
1907
1908void Assembler::fwait() {
1909 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001910 EMIT(0x9B);
1911}
1912
1913
1914void Assembler::frndint() {
1915 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001916 EMIT(0xD9);
1917 EMIT(0xFC);
1918}
1919
1920
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001921void Assembler::fnclex() {
1922 EnsureSpace ensure_space(this);
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001923 EMIT(0xDB);
1924 EMIT(0xE2);
1925}
1926
1927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001928void Assembler::sahf() {
1929 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001930 EMIT(0x9E);
1931}
1932
1933
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001934void Assembler::setcc(Condition cc, Register reg) {
1935 ASSERT(reg.is_byte_register());
1936 EnsureSpace ensure_space(this);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001937 EMIT(0x0F);
1938 EMIT(0x90 | cc);
1939 EMIT(0xC0 | reg.code());
1940}
1941
1942
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001943void Assembler::cvttss2si(Register dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001944 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001945 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001946 EMIT(0xF3);
1947 EMIT(0x0F);
1948 EMIT(0x2C);
1949 emit_operand(dst, src);
1950}
1951
1952
1953void Assembler::cvttsd2si(Register dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001954 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001955 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001956 EMIT(0xF2);
1957 EMIT(0x0F);
1958 EMIT(0x2C);
1959 emit_operand(dst, src);
1960}
1961
1962
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001963void Assembler::cvtsd2si(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001964 ASSERT(IsEnabled(SSE2));
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001965 EnsureSpace ensure_space(this);
1966 EMIT(0xF2);
1967 EMIT(0x0F);
1968 EMIT(0x2D);
1969 emit_sse_operand(dst, src);
1970}
1971
1972
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001973void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001974 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001975 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001976 EMIT(0xF2);
1977 EMIT(0x0F);
1978 EMIT(0x2A);
1979 emit_sse_operand(dst, src);
1980}
1981
1982
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001983void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001984 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001985 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001986 EMIT(0xF3);
1987 EMIT(0x0F);
1988 EMIT(0x5A);
1989 emit_sse_operand(dst, src);
1990}
1991
1992
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001993void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001994 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001995 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001996 EMIT(0xF2);
1997 EMIT(0x0F);
1998 EMIT(0x5A);
1999 emit_sse_operand(dst, src);
2000}
2001
2002
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002003void Assembler::addsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002004 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002005 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002006 EMIT(0xF2);
2007 EMIT(0x0F);
2008 EMIT(0x58);
2009 emit_sse_operand(dst, src);
2010}
2011
2012
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002013void Assembler::addsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002014 ASSERT(IsEnabled(SSE2));
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002015 EnsureSpace ensure_space(this);
2016 EMIT(0xF2);
2017 EMIT(0x0F);
2018 EMIT(0x58);
2019 emit_sse_operand(dst, src);
2020}
2021
2022
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002023void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002024 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002025 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026 EMIT(0xF2);
2027 EMIT(0x0F);
2028 EMIT(0x59);
2029 emit_sse_operand(dst, src);
2030}
2031
2032
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002033void Assembler::mulsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002034 ASSERT(IsEnabled(SSE2));
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002035 EnsureSpace ensure_space(this);
2036 EMIT(0xF2);
2037 EMIT(0x0F);
2038 EMIT(0x59);
2039 emit_sse_operand(dst, src);
2040}
2041
2042
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043void Assembler::subsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002044 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002046 EMIT(0xF2);
2047 EMIT(0x0F);
2048 EMIT(0x5C);
2049 emit_sse_operand(dst, src);
2050}
2051
2052
2053void Assembler::divsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002054 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002056 EMIT(0xF2);
2057 EMIT(0x0F);
2058 EMIT(0x5E);
2059 emit_sse_operand(dst, src);
2060}
2061
2062
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002063void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002064 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002065 EnsureSpace ensure_space(this);
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002066 EMIT(0x66);
2067 EMIT(0x0F);
2068 EMIT(0x57);
2069 emit_sse_operand(dst, src);
2070}
2071
2072
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002073void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2074 EnsureSpace ensure_space(this);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002075 EMIT(0x0F);
2076 EMIT(0x57);
2077 emit_sse_operand(dst, src);
2078}
2079
2080
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002081void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2082 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002083 EMIT(0xF2);
2084 EMIT(0x0F);
2085 EMIT(0x51);
2086 emit_sse_operand(dst, src);
2087}
2088
2089
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002090void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2091 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002092 EMIT(0x66);
2093 EMIT(0x0F);
2094 EMIT(0x54);
2095 emit_sse_operand(dst, src);
2096}
2097
2098
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00002099void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2100 EnsureSpace ensure_space(this);
2101 EMIT(0x66);
2102 EMIT(0x0F);
2103 EMIT(0x56);
2104 emit_sse_operand(dst, src);
2105}
2106
2107
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002108void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002109 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002110 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002111 EMIT(0x66);
2112 EMIT(0x0F);
2113 EMIT(0x2E);
2114 emit_sse_operand(dst, src);
2115}
2116
2117
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002118void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002119 ASSERT(IsEnabled(SSE2));
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002120 EnsureSpace ensure_space(this);
2121 EMIT(0x66);
2122 EMIT(0x0F);
2123 EMIT(0x2E);
2124 emit_sse_operand(dst, src);
2125}
2126
2127
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002128void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002129 ASSERT(IsEnabled(SSE4_1));
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002130 EnsureSpace ensure_space(this);
2131 EMIT(0x66);
2132 EMIT(0x0F);
2133 EMIT(0x3A);
2134 EMIT(0x0B);
2135 emit_sse_operand(dst, src);
2136 // Mask precision exeption.
2137 EMIT(static_cast<byte>(mode) | 0x8);
2138}
2139
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002140void Assembler::movmskpd(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002141 ASSERT(IsEnabled(SSE2));
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002142 EnsureSpace ensure_space(this);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002143 EMIT(0x66);
2144 EMIT(0x0F);
2145 EMIT(0x50);
2146 emit_sse_operand(dst, src);
2147}
2148
2149
ulan@chromium.org4121f232012-12-27 15:57:11 +00002150void Assembler::movmskps(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002151 ASSERT(IsEnabled(SSE2));
ulan@chromium.org4121f232012-12-27 15:57:11 +00002152 EnsureSpace ensure_space(this);
2153 EMIT(0x0F);
2154 EMIT(0x50);
2155 emit_sse_operand(dst, src);
2156}
2157
2158
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002159void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002160 ASSERT(IsEnabled(SSE2));
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002161 EnsureSpace ensure_space(this);
2162 EMIT(0x66);
2163 EMIT(0x0F);
2164 EMIT(0x76);
2165 emit_sse_operand(dst, src);
2166}
2167
2168
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002169void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002170 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002171 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002172 EMIT(0xF2);
2173 EMIT(0x0F);
2174 EMIT(0xC2);
2175 emit_sse_operand(dst, src);
2176 EMIT(1); // LT == 1
2177}
2178
2179
2180void Assembler::movaps(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002181 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002182 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002183 EMIT(0x0F);
2184 EMIT(0x28);
2185 emit_sse_operand(dst, src);
2186}
2187
2188
2189void Assembler::movdqa(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002190 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002191 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002192 EMIT(0x66);
2193 EMIT(0x0F);
2194 EMIT(0x7F);
2195 emit_sse_operand(src, dst);
2196}
2197
2198
2199void Assembler::movdqa(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002200 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002201 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002202 EMIT(0x66);
2203 EMIT(0x0F);
2204 EMIT(0x6F);
2205 emit_sse_operand(dst, src);
2206}
2207
2208
2209void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002210 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002211 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002212 EMIT(0xF3);
2213 EMIT(0x0F);
2214 EMIT(0x7F);
2215 emit_sse_operand(src, dst);
2216}
2217
2218
2219void Assembler::movdqu(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002220 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002221 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002222 EMIT(0xF3);
2223 EMIT(0x0F);
2224 EMIT(0x6F);
2225 emit_sse_operand(dst, src);
2226}
2227
2228
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002229void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002230 ASSERT(IsEnabled(SSE4_1));
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002231 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002232 EMIT(0x66);
2233 EMIT(0x0F);
2234 EMIT(0x38);
2235 EMIT(0x2A);
2236 emit_sse_operand(dst, src);
2237}
2238
2239
2240void Assembler::movntdq(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002241 ASSERT(IsEnabled(SSE2));
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002242 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002243 EMIT(0x66);
2244 EMIT(0x0F);
2245 EMIT(0xE7);
2246 emit_sse_operand(src, dst);
2247}
2248
2249
2250void Assembler::prefetch(const Operand& src, int level) {
2251 ASSERT(is_uint2(level));
2252 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002253 EMIT(0x0F);
2254 EMIT(0x18);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002255 // Emit hint number in Reg position of RegR/M.
2256 XMMRegister code = XMMRegister::from_code(level);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002257 emit_sse_operand(code, src);
2258}
2259
2260
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002261void Assembler::movdbl(XMMRegister dst, const Operand& src) {
2262 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002263 movsd(dst, src);
2264}
2265
2266
2267void Assembler::movdbl(const Operand& dst, XMMRegister src) {
2268 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269 movsd(dst, src);
2270}
2271
2272
2273void Assembler::movsd(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002274 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002276 EMIT(0xF2); // double
2277 EMIT(0x0F);
2278 EMIT(0x11); // store
2279 emit_sse_operand(src, dst);
2280}
2281
2282
2283void Assembler::movsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002284 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002285 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002286 EMIT(0xF2); // double
2287 EMIT(0x0F);
2288 EMIT(0x10); // load
2289 emit_sse_operand(dst, src);
2290}
2291
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002292
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002293void Assembler::movsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002294 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002295 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002296 EMIT(0xF2);
2297 EMIT(0x0F);
2298 EMIT(0x10);
2299 emit_sse_operand(dst, src);
2300}
2301
2302
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002303void Assembler::movss(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002304 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002305 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002306 EMIT(0xF3); // float
2307 EMIT(0x0F);
2308 EMIT(0x11); // store
2309 emit_sse_operand(src, dst);
2310}
2311
2312
2313void Assembler::movss(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002314 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002315 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002316 EMIT(0xF3); // float
2317 EMIT(0x0F);
2318 EMIT(0x10); // load
2319 emit_sse_operand(dst, src);
2320}
2321
2322
2323void Assembler::movss(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002324 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002325 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002326 EMIT(0xF3);
2327 EMIT(0x0F);
2328 EMIT(0x10);
2329 emit_sse_operand(dst, src);
2330}
2331
2332
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002333void Assembler::movd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002334 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002335 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002336 EMIT(0x66);
2337 EMIT(0x0F);
2338 EMIT(0x6E);
2339 emit_sse_operand(dst, src);
2340}
2341
2342
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002343void Assembler::movd(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002344 ASSERT(IsEnabled(SSE2));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002345 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002346 EMIT(0x66);
2347 EMIT(0x0F);
2348 EMIT(0x7E);
2349 emit_sse_operand(src, dst);
2350}
2351
2352
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002353void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2354 ASSERT(CpuFeatures::IsSupported(SSE4_1));
2355 ASSERT(is_uint8(imm8));
2356 EnsureSpace ensure_space(this);
2357 EMIT(0x66);
2358 EMIT(0x0F);
2359 EMIT(0x3A);
2360 EMIT(0x17);
2361 emit_sse_operand(dst, src);
2362 EMIT(imm8);
2363}
2364
2365
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002366void Assembler::pand(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002367 ASSERT(IsEnabled(SSE2));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002368 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002369 EMIT(0x66);
2370 EMIT(0x0F);
2371 EMIT(0xDB);
2372 emit_sse_operand(dst, src);
2373}
2374
2375
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002376void Assembler::pxor(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002377 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002378 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002379 EMIT(0x66);
2380 EMIT(0x0F);
2381 EMIT(0xEF);
2382 emit_sse_operand(dst, src);
2383}
2384
2385
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002386void Assembler::por(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002387 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002388 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002389 EMIT(0x66);
2390 EMIT(0x0F);
2391 EMIT(0xEB);
2392 emit_sse_operand(dst, src);
2393}
2394
2395
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002396void Assembler::ptest(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002397 ASSERT(IsEnabled(SSE4_1));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002398 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002399 EMIT(0x66);
2400 EMIT(0x0F);
2401 EMIT(0x38);
2402 EMIT(0x17);
2403 emit_sse_operand(dst, src);
2404}
2405
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002406
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002407void Assembler::psllq(XMMRegister reg, int8_t shift) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002408 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002409 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002410 EMIT(0x66);
2411 EMIT(0x0F);
2412 EMIT(0x73);
2413 emit_sse_operand(esi, reg); // esi == 6
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002414 EMIT(shift);
2415}
2416
2417
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002418void Assembler::psllq(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002419 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002420 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002421 EMIT(0x66);
2422 EMIT(0x0F);
2423 EMIT(0xF3);
2424 emit_sse_operand(dst, src);
2425}
2426
2427
2428void Assembler::psrlq(XMMRegister reg, int8_t shift) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002429 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002430 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002431 EMIT(0x66);
2432 EMIT(0x0F);
2433 EMIT(0x73);
2434 emit_sse_operand(edx, reg); // edx == 2
2435 EMIT(shift);
2436}
2437
2438
2439void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002440 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002441 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002442 EMIT(0x66);
2443 EMIT(0x0F);
2444 EMIT(0xD3);
2445 emit_sse_operand(dst, src);
2446}
2447
2448
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002449void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002450 ASSERT(IsEnabled(SSE2));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002451 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002452 EMIT(0x66);
2453 EMIT(0x0F);
2454 EMIT(0x70);
2455 emit_sse_operand(dst, src);
2456 EMIT(shuffle);
2457}
2458
2459
2460void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002461 ASSERT(IsEnabled(SSE4_1));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002462 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002463 EMIT(0x66);
2464 EMIT(0x0F);
2465 EMIT(0x3A);
2466 EMIT(0x16);
2467 emit_sse_operand(src, dst);
2468 EMIT(offset);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002469}
2470
2471
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002472void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002473 ASSERT(IsEnabled(SSE4_1));
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002474 EnsureSpace ensure_space(this);
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002475 EMIT(0x66);
2476 EMIT(0x0F);
2477 EMIT(0x3A);
2478 EMIT(0x22);
2479 emit_sse_operand(dst, src);
2480 EMIT(offset);
2481}
2482
2483
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002484void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2485 Register ireg = { reg.code() };
2486 emit_operand(ireg, adr);
2487}
2488
2489
2490void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2491 EMIT(0xC0 | dst.code() << 3 | src.code());
2492}
2493
2494
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002495void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2496 EMIT(0xC0 | dst.code() << 3 | src.code());
2497}
2498
2499
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002500void Assembler::Print() {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002501 Disassembler::Decode(isolate(), stdout, buffer_, pc_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002502}
2503
2504
2505void Assembler::RecordJSReturn() {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002506 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002507 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00002508 RecordRelocInfo(RelocInfo::JS_RETURN);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002509}
2510
2511
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002512void Assembler::RecordDebugBreakSlot() {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002513 positions_recorder()->WriteRecordedPositions();
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002514 EnsureSpace ensure_space(this);
2515 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2516}
2517
2518
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002519void Assembler::RecordComment(const char* msg, bool force) {
2520 if (FLAG_code_comments || force) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002521 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00002522 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002523 }
2524}
2525
2526
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002527void Assembler::GrowBuffer() {
ager@chromium.org5c838252010-02-19 08:53:10 +00002528 ASSERT(overflow());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002529 if (!own_buffer_) FATAL("external code buffer is too small");
2530
ager@chromium.org5c838252010-02-19 08:53:10 +00002531 // Compute new buffer size.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002532 CodeDesc desc; // the new buffer
2533 if (buffer_size_ < 4*KB) {
2534 desc.buffer_size = 4*KB;
2535 } else {
2536 desc.buffer_size = 2*buffer_size_;
2537 }
2538 // Some internal data structures overflow for very large buffers,
2539 // they must ensure that kMaximalBufferSize is not too large.
2540 if ((desc.buffer_size > kMaximalBufferSize) ||
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002541 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002542 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2543 }
2544
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002545 // Set up new buffer.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002546 desc.buffer = NewArray<byte>(desc.buffer_size);
2547 desc.instr_size = pc_offset();
2548 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2549
2550 // Clear the buffer in debug mode. Use 'int3' instructions to make
2551 // sure to get into problems if we ever run uninitialized code.
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002552#ifdef DEBUG
2553 memset(desc.buffer, 0xCC, desc.buffer_size);
2554#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002555
ager@chromium.org5c838252010-02-19 08:53:10 +00002556 // Copy the data.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002557 int pc_delta = desc.buffer - buffer_;
2558 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002559 OS::MemMove(desc.buffer, buffer_, desc.instr_size);
2560 OS::MemMove(rc_delta + reloc_info_writer.pos(),
2561 reloc_info_writer.pos(), desc.reloc_size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002562
ager@chromium.org5c838252010-02-19 08:53:10 +00002563 // Switch buffers.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002564 if (isolate()->assembler_spare_buffer() == NULL &&
2565 buffer_size_ == kMinimalBufferSize) {
2566 isolate()->set_assembler_spare_buffer(buffer_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002567 } else {
2568 DeleteArray(buffer_);
2569 }
2570 buffer_ = desc.buffer;
2571 buffer_size_ = desc.buffer_size;
2572 pc_ += pc_delta;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002573 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2574 reloc_info_writer.last_pc() + pc_delta);
2575
ager@chromium.org5c838252010-02-19 08:53:10 +00002576 // Relocate runtime entries.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002577 for (RelocIterator it(desc); !it.done(); it.next()) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002578 RelocInfo::Mode rmode = it.rinfo()->rmode();
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00002579 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002580 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2581 if (*p != 0) { // 0 means uninitialized.
2582 *p += pc_delta;
2583 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002584 }
2585 }
2586
2587 ASSERT(!overflow());
2588}
2589
2590
2591void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
2592 ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode
2593 ASSERT(is_uint8(imm8));
2594 ASSERT((op1 & 0x01) == 0); // should be 8bit operation
2595 EMIT(op1);
2596 EMIT(op2 | dst.code());
2597 EMIT(imm8);
2598}
2599
2600
2601void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
2602 ASSERT((0 <= sel) && (sel <= 7));
2603 Register ireg = { sel };
2604 if (x.is_int8()) {
2605 EMIT(0x83); // using a sign-extended 8-bit immediate.
2606 emit_operand(ireg, dst);
2607 EMIT(x.x_ & 0xFF);
2608 } else if (dst.is_reg(eax)) {
2609 EMIT((sel << 3) | 0x05); // short form if the destination is eax.
2610 emit(x);
2611 } else {
2612 EMIT(0x81); // using a literal 32-bit immediate.
2613 emit_operand(ireg, dst);
2614 emit(x);
2615 }
2616}
2617
2618
2619void Assembler::emit_operand(Register reg, const Operand& adr) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002620 const unsigned length = adr.len_;
2621 ASSERT(length > 0);
2622
2623 // Emit updated ModRM byte containing the given register.
2624 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2625
2626 // Emit the rest of the encoded operand.
2627 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2628 pc_ += length;
2629
2630 // Emit relocation information if necessary.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002631 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002632 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32
2633 RecordRelocInfo(adr.rmode_);
2634 pc_ += sizeof(int32_t);
2635 }
2636}
2637
2638
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002639void Assembler::emit_farith(int b1, int b2, int i) {
2640 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2641 ASSERT(0 <= i && i < 8); // illegal stack offset
2642 EMIT(b1);
2643 EMIT(b2 + i);
2644}
2645
2646
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002647void Assembler::db(uint8_t data) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002648 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002649 EMIT(data);
2650}
2651
2652
2653void Assembler::dd(uint32_t data) {
2654 EnsureSpace ensure_space(this);
2655 emit(data);
ager@chromium.org236ad962008-09-25 09:45:57 +00002656}
2657
2658
2659void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002660 ASSERT(!RelocInfo::IsNone(rmode));
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00002661 // Don't record external references unless the heap will be serialized.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002662 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2663#ifdef DEBUG
2664 if (!Serializer::enabled()) {
2665 Serializer::TooLateToEnableNow();
2666 }
2667#endif
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00002668 if (!Serializer::enabled() && !emit_debug_code()) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002669 return;
2670 }
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00002671 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002672 RelocInfo rinfo(pc_, rmode, data, NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002673 reloc_info_writer.Write(&rinfo);
2674}
2675
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002676
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002677#ifdef GENERATED_CODE_COVERAGE
2678static FILE* coverage_log = NULL;
2679
2680
2681static void InitCoverageLog() {
2682 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
2683 if (file_name != NULL) {
2684 coverage_log = fopen(file_name, "aw+");
2685 }
2686}
2687
2688
2689void LogGeneratedCodeCoverage(const char* file_line) {
2690 const char* return_address = (&file_line)[-1];
2691 char* push_insn = const_cast<char*>(return_address - 12);
2692 push_insn[0] = 0xeb; // Relative branch insn.
2693 push_insn[1] = 13; // Skip over coverage insns.
2694 if (coverage_log != NULL) {
2695 fprintf(coverage_log, "%s\n", file_line);
2696 fflush(coverage_log);
2697 }
2698}
2699
2700#endif
2701
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002702} } // namespace v8::internal
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002703
2704#endif // V8_TARGET_ARCH_IA32