blob: 7bea37302589ed52c1759d7f3abb268b5b1ab5d2 [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
jkummerow@chromium.org93a47f42013-07-02 14:43:41 +000039#if V8_TARGET_ARCH_IA32
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +000040
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 {
danno@chromium.org169691d2013-07-15 08:01:13 +000068 return X87Register::kNumAllocatableRegisters;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000069 }
70}
71
72
73int IntelDoubleRegister::NumRegisters() {
74 if (CpuFeatures::IsSupported(SSE2)) {
75 return XMMRegister::kNumRegisters;
76 } else {
danno@chromium.org169691d2013-07-15 08:01:13 +000077 return X87Register::kNumRegisters;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000078 }
79}
80
81
82const char* IntelDoubleRegister::AllocationIndexToString(int index) {
83 if (CpuFeatures::IsSupported(SSE2)) {
84 return XMMRegister::AllocationIndexToString(index);
85 } else {
danno@chromium.org169691d2013-07-15 08:01:13 +000086 return X87Register::AllocationIndexToString(index);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000087 }
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
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001058
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00001059void Assembler::ror(Register dst, uint8_t imm8) {
1060 EnsureSpace ensure_space(this);
1061 ASSERT(is_uint5(imm8)); // illegal shift count
1062 if (imm8 == 1) {
1063 EMIT(0xD1);
1064 EMIT(0xC8 | dst.code());
1065 } else {
1066 EMIT(0xC1);
1067 EMIT(0xC8 | dst.code());
1068 EMIT(imm8);
1069 }
1070}
1071
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001072
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00001073void Assembler::ror_cl(Register dst) {
1074 EnsureSpace ensure_space(this);
1075 EMIT(0xD3);
1076 EMIT(0xC8 | dst.code());
1077}
1078
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00001079
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001080void Assembler::sar(Register dst, uint8_t imm8) {
1081 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001082 ASSERT(is_uint5(imm8)); // illegal shift count
1083 if (imm8 == 1) {
1084 EMIT(0xD1);
1085 EMIT(0xF8 | dst.code());
1086 } else {
1087 EMIT(0xC1);
1088 EMIT(0xF8 | dst.code());
1089 EMIT(imm8);
1090 }
1091}
1092
1093
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001094void Assembler::sar_cl(Register dst) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001095 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001096 EMIT(0xD3);
1097 EMIT(0xF8 | dst.code());
1098}
1099
1100
1101void Assembler::sbb(Register dst, const Operand& src) {
1102 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001103 EMIT(0x1B);
1104 emit_operand(dst, src);
1105}
1106
1107
1108void Assembler::shld(Register dst, const Operand& src) {
1109 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001110 EMIT(0x0F);
1111 EMIT(0xA5);
1112 emit_operand(dst, src);
1113}
1114
1115
1116void Assembler::shl(Register dst, uint8_t imm8) {
1117 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001118 ASSERT(is_uint5(imm8)); // illegal shift count
1119 if (imm8 == 1) {
1120 EMIT(0xD1);
1121 EMIT(0xE0 | dst.code());
1122 } else {
1123 EMIT(0xC1);
1124 EMIT(0xE0 | dst.code());
1125 EMIT(imm8);
1126 }
1127}
1128
1129
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001130void Assembler::shl_cl(Register dst) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001131 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001132 EMIT(0xD3);
1133 EMIT(0xE0 | dst.code());
1134}
1135
1136
1137void Assembler::shrd(Register dst, const Operand& src) {
1138 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001139 EMIT(0x0F);
1140 EMIT(0xAD);
1141 emit_operand(dst, src);
1142}
1143
1144
1145void Assembler::shr(Register dst, uint8_t imm8) {
1146 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001147 ASSERT(is_uint5(imm8)); // illegal shift count
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001148 if (imm8 == 1) {
1149 EMIT(0xD1);
1150 EMIT(0xE8 | dst.code());
1151 } else {
1152 EMIT(0xC1);
1153 EMIT(0xE8 | dst.code());
1154 EMIT(imm8);
1155 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001156}
1157
1158
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001159void Assembler::shr_cl(Register dst) {
1160 EnsureSpace ensure_space(this);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001161 EMIT(0xD3);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001162 EMIT(0xE8 | dst.code());
1163}
1164
1165
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001166void Assembler::sub(const Operand& dst, const Immediate& x) {
1167 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001168 emit_arith(5, dst, x);
1169}
1170
1171
1172void Assembler::sub(Register dst, const Operand& src) {
1173 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001174 EMIT(0x2B);
1175 emit_operand(dst, src);
1176}
1177
1178
1179void Assembler::sub(const Operand& dst, Register src) {
1180 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001181 EMIT(0x29);
ager@chromium.org3bf7b912008-11-17 09:09:45 +00001182 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001183}
1184
1185
1186void Assembler::test(Register reg, const Immediate& imm) {
1187 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001188 // Only use test against byte for registers that have a byte
1189 // variant: eax, ebx, ecx, and edx.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001190 if (RelocInfo::IsNone(imm.rmode_) &&
yangguo@chromium.org56454712012-02-16 15:33:53 +00001191 is_uint8(imm.x_) &&
1192 reg.is_byte_register()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193 uint8_t imm8 = imm.x_;
1194 if (reg.is(eax)) {
1195 EMIT(0xA8);
1196 EMIT(imm8);
1197 } else {
1198 emit_arith_b(0xF6, 0xC0, reg, imm8);
1199 }
1200 } else {
1201 // This is not using emit_arith because test doesn't support
1202 // sign-extension of 8-bit operands.
1203 if (reg.is(eax)) {
1204 EMIT(0xA9);
1205 } else {
1206 EMIT(0xF7);
1207 EMIT(0xC0 | reg.code());
1208 }
1209 emit(imm);
1210 }
1211}
1212
1213
1214void Assembler::test(Register reg, const Operand& op) {
1215 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001216 EMIT(0x85);
1217 emit_operand(reg, op);
1218}
1219
1220
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001221void Assembler::test_b(Register reg, const Operand& op) {
yangguo@chromium.org56454712012-02-16 15:33:53 +00001222 CHECK(reg.is_byte_register());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001223 EnsureSpace ensure_space(this);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001224 EMIT(0x84);
1225 emit_operand(reg, op);
1226}
1227
1228
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001229void Assembler::test(const Operand& op, const Immediate& imm) {
danno@chromium.org59400602013-08-13 17:09:37 +00001230 if (op.is_reg_only()) {
1231 test(op.reg(), imm);
1232 return;
1233 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001234 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001235 EMIT(0xF7);
1236 emit_operand(eax, op);
1237 emit(imm);
1238}
1239
1240
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001241void Assembler::test_b(const Operand& op, uint8_t imm8) {
yangguo@chromium.org56454712012-02-16 15:33:53 +00001242 if (op.is_reg_only() && !op.reg().is_byte_register()) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001243 test(op, Immediate(imm8));
1244 return;
1245 }
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001246 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001247 EMIT(0xF6);
1248 emit_operand(eax, op);
1249 EMIT(imm8);
1250}
1251
1252
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001253void Assembler::xor_(Register dst, int32_t imm32) {
1254 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001255 emit_arith(6, Operand(dst), Immediate(imm32));
1256}
1257
1258
1259void Assembler::xor_(Register dst, const Operand& src) {
1260 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001261 EMIT(0x33);
1262 emit_operand(dst, src);
1263}
1264
1265
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001266void Assembler::xor_(const Operand& dst, Register src) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001267 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001268 EMIT(0x31);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001269 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001270}
1271
1272
1273void Assembler::xor_(const Operand& dst, const Immediate& x) {
1274 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001275 emit_arith(6, dst, x);
1276}
1277
1278
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001279void Assembler::bt(const Operand& dst, Register src) {
1280 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001281 EMIT(0x0F);
1282 EMIT(0xA3);
1283 emit_operand(src, dst);
1284}
1285
1286
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001287void Assembler::bts(const Operand& dst, Register src) {
1288 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001289 EMIT(0x0F);
1290 EMIT(0xAB);
1291 emit_operand(src, dst);
1292}
1293
1294
1295void Assembler::hlt() {
1296 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001297 EMIT(0xF4);
1298}
1299
1300
1301void Assembler::int3() {
1302 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001303 EMIT(0xCC);
1304}
1305
1306
1307void Assembler::nop() {
1308 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001309 EMIT(0x90);
1310}
1311
1312
1313void Assembler::rdtsc() {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001314 ASSERT(IsEnabled(RDTSC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001315 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001316 EMIT(0x0F);
1317 EMIT(0x31);
1318}
1319
1320
1321void Assembler::ret(int imm16) {
1322 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001323 ASSERT(is_uint16(imm16));
1324 if (imm16 == 0) {
1325 EMIT(0xC3);
1326 } else {
1327 EMIT(0xC2);
1328 EMIT(imm16 & 0xFF);
1329 EMIT((imm16 >> 8) & 0xFF);
1330 }
1331}
1332
1333
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001334// Labels refer to positions in the (to be) generated code.
1335// There are bound, linked, and unused labels.
1336//
1337// Bound labels refer to known positions in the already
1338// generated code. pos() is the position the label refers to.
1339//
1340// Linked labels refer to unknown positions in the code
1341// to be generated; pos() is the position of the 32bit
1342// Displacement of the last instruction using the label.
1343
1344
1345void Assembler::print(Label* L) {
1346 if (L->is_unused()) {
1347 PrintF("unused label\n");
1348 } else if (L->is_bound()) {
1349 PrintF("bound label to %d\n", L->pos());
1350 } else if (L->is_linked()) {
1351 Label l = *L;
1352 PrintF("unbound label");
1353 while (l.is_linked()) {
1354 Displacement disp = disp_at(&l);
1355 PrintF("@ %d ", l.pos());
1356 disp.print();
1357 PrintF("\n");
1358 disp.next(&l);
1359 }
1360 } else {
1361 PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1362 }
1363}
1364
1365
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001366void Assembler::bind_to(Label* L, int pos) {
1367 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position
1369 while (L->is_linked()) {
1370 Displacement disp = disp_at(L);
1371 int fixup_pos = L->pos();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001372 if (disp.type() == Displacement::CODE_RELATIVE) {
1373 // Relative to Code* heap object pointer.
1374 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1375 } else {
1376 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1377 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
1378 }
ager@chromium.org5c838252010-02-19 08:53:10 +00001379 // Relative address, relative to point after address.
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001380 int imm32 = pos - (fixup_pos + sizeof(int32_t));
1381 long_at_put(fixup_pos, imm32);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001382 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001383 disp.next(L);
1384 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001385 while (L->is_near_linked()) {
1386 int fixup_pos = L->near_link_pos();
1387 int offset_to_next =
1388 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
1389 ASSERT(offset_to_next <= 0);
1390 // Relative address, relative to point after address.
1391 int disp = pos - fixup_pos - sizeof(int8_t);
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00001392 CHECK(0 <= disp && disp <= 127);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001393 set_byte_at(fixup_pos, disp);
1394 if (offset_to_next < 0) {
1395 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1396 } else {
1397 L->UnuseNear();
1398 }
1399 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400 L->bind_to(pos);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001401}
1402
1403
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001404void Assembler::bind(Label* L) {
1405 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001406 ASSERT(!L->is_bound()); // label can only be bound once
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407 bind_to(L, pc_offset());
1408}
1409
1410
1411void Assembler::call(Label* L) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001412 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001413 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001414 if (L->is_bound()) {
1415 const int long_size = 5;
1416 int offs = L->pos() - pc_offset();
1417 ASSERT(offs <= 0);
ager@chromium.org5c838252010-02-19 08:53:10 +00001418 // 1110 1000 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419 EMIT(0xE8);
1420 emit(offs - long_size);
1421 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001422 // 1110 1000 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001423 EMIT(0xE8);
1424 emit_disp(L, Displacement::OTHER);
1425 }
1426}
1427
1428
ager@chromium.org236ad962008-09-25 09:45:57 +00001429void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001430 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001431 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001432 ASSERT(!RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001433 EMIT(0xE8);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001434 if (RelocInfo::IsRuntimeEntry(rmode)) {
1435 emit(reinterpret_cast<uint32_t>(entry), rmode);
1436 } else {
1437 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1438 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439}
1440
1441
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001442int Assembler::CallSize(const Operand& adr) {
1443 // Call size is 1 (opcode) + adr.len_ (operand).
1444 return 1 + adr.len_;
1445}
1446
1447
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001448void Assembler::call(const Operand& adr) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001451 EMIT(0xFF);
1452 emit_operand(edx, adr);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001453}
1454
1455
1456int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1457 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001458}
1459
1460
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001461void Assembler::call(Handle<Code> code,
1462 RelocInfo::Mode rmode,
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001463 TypeFeedbackId ast_id) {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00001464 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001465 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001466 ASSERT(RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001467 EMIT(0xE8);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001468 emit(code, rmode, ast_id);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469}
1470
1471
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001472void Assembler::jmp(Label* L, Label::Distance distance) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474 if (L->is_bound()) {
1475 const int short_size = 2;
1476 const int long_size = 5;
1477 int offs = L->pos() - pc_offset();
1478 ASSERT(offs <= 0);
1479 if (is_int8(offs - short_size)) {
ager@chromium.org5c838252010-02-19 08:53:10 +00001480 // 1110 1011 #8-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001481 EMIT(0xEB);
1482 EMIT((offs - short_size) & 0xFF);
1483 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001484 // 1110 1001 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001485 EMIT(0xE9);
1486 emit(offs - long_size);
1487 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001488 } else if (distance == Label::kNear) {
1489 EMIT(0xEB);
1490 emit_near_disp(L);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001491 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001492 // 1110 1001 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493 EMIT(0xE9);
1494 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1495 }
1496}
1497
1498
ager@chromium.org236ad962008-09-25 09:45:57 +00001499void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001500 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001501 ASSERT(!RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001502 EMIT(0xE9);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001503 if (RelocInfo::IsRuntimeEntry(rmode)) {
1504 emit(reinterpret_cast<uint32_t>(entry), rmode);
1505 } else {
1506 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1507 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001508}
1509
1510
1511void Assembler::jmp(const Operand& adr) {
1512 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001513 EMIT(0xFF);
1514 emit_operand(esp, adr);
1515}
1516
1517
ager@chromium.org236ad962008-09-25 09:45:57 +00001518void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001519 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001520 ASSERT(RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521 EMIT(0xE9);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001522 emit(code, rmode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001523}
1524
1525
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001526void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001527 EnsureSpace ensure_space(this);
danno@chromium.org72204d52012-10-31 10:02:10 +00001528 ASSERT(0 <= cc && static_cast<int>(cc) < 16);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001529 if (L->is_bound()) {
1530 const int short_size = 2;
1531 const int long_size = 6;
1532 int offs = L->pos() - pc_offset();
1533 ASSERT(offs <= 0);
1534 if (is_int8(offs - short_size)) {
1535 // 0111 tttn #8-bit disp
1536 EMIT(0x70 | cc);
1537 EMIT((offs - short_size) & 0xFF);
1538 } else {
1539 // 0000 1111 1000 tttn #32-bit disp
1540 EMIT(0x0F);
1541 EMIT(0x80 | cc);
1542 emit(offs - long_size);
1543 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001544 } else if (distance == Label::kNear) {
1545 EMIT(0x70 | cc);
1546 emit_near_disp(L);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001547 } else {
1548 // 0000 1111 1000 tttn #32-bit disp
1549 // Note: could eliminate cond. jumps to this jump if condition
1550 // is the same however, seems to be rather unlikely case.
1551 EMIT(0x0F);
1552 EMIT(0x80 | cc);
1553 emit_disp(L, Displacement::OTHER);
1554 }
1555}
1556
1557
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001558void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001559 EnsureSpace ensure_space(this);
danno@chromium.org72204d52012-10-31 10:02:10 +00001560 ASSERT((0 <= cc) && (static_cast<int>(cc) < 16));
ager@chromium.org5c838252010-02-19 08:53:10 +00001561 // 0000 1111 1000 tttn #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001562 EMIT(0x0F);
1563 EMIT(0x80 | cc);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001564 if (RelocInfo::IsRuntimeEntry(rmode)) {
1565 emit(reinterpret_cast<uint32_t>(entry), rmode);
1566 } else {
1567 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1568 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001569}
1570
1571
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001572void Assembler::j(Condition cc, Handle<Code> code) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001573 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001574 // 0000 1111 1000 tttn #32-bit disp
1575 EMIT(0x0F);
1576 EMIT(0x80 | cc);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001577 emit(code, RelocInfo::CODE_TARGET);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001578}
1579
1580
ager@chromium.org5c838252010-02-19 08:53:10 +00001581// FPU instructions.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001582
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001583void Assembler::fld(int i) {
1584 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585 emit_farith(0xD9, 0xC0, i);
1586}
1587
1588
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001589void Assembler::fstp(int i) {
1590 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001591 emit_farith(0xDD, 0xD8, i);
1592}
1593
1594
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001595void Assembler::fld1() {
1596 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001597 EMIT(0xD9);
1598 EMIT(0xE8);
1599}
1600
1601
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001602void Assembler::fldpi() {
1603 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001604 EMIT(0xD9);
1605 EMIT(0xEB);
1606}
1607
1608
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609void Assembler::fldz() {
1610 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001611 EMIT(0xD9);
1612 EMIT(0xEE);
1613}
1614
1615
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001616void Assembler::fldln2() {
1617 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618 EMIT(0xD9);
1619 EMIT(0xED);
1620}
1621
1622
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623void Assembler::fld_s(const Operand& adr) {
1624 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625 EMIT(0xD9);
1626 emit_operand(eax, adr);
1627}
1628
1629
1630void Assembler::fld_d(const Operand& adr) {
1631 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632 EMIT(0xDD);
1633 emit_operand(eax, adr);
1634}
1635
1636
1637void Assembler::fstp_s(const Operand& adr) {
1638 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001639 EMIT(0xD9);
1640 emit_operand(ebx, adr);
1641}
1642
1643
1644void Assembler::fstp_d(const Operand& adr) {
1645 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001646 EMIT(0xDD);
1647 emit_operand(ebx, adr);
1648}
1649
1650
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001651void Assembler::fst_d(const Operand& adr) {
1652 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001653 EMIT(0xDD);
1654 emit_operand(edx, adr);
1655}
1656
1657
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001658void Assembler::fild_s(const Operand& adr) {
1659 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001660 EMIT(0xDB);
1661 emit_operand(eax, adr);
1662}
1663
1664
1665void Assembler::fild_d(const Operand& adr) {
1666 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001667 EMIT(0xDF);
1668 emit_operand(ebp, adr);
1669}
1670
1671
1672void Assembler::fistp_s(const Operand& adr) {
1673 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001674 EMIT(0xDB);
1675 emit_operand(ebx, adr);
1676}
1677
1678
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001679void Assembler::fisttp_s(const Operand& adr) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001680 ASSERT(IsEnabled(SSE3));
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001681 EnsureSpace ensure_space(this);
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001682 EMIT(0xDB);
1683 emit_operand(ecx, adr);
1684}
1685
1686
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001687void Assembler::fisttp_d(const Operand& adr) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001688 ASSERT(IsEnabled(SSE3));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001689 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001690 EMIT(0xDD);
1691 emit_operand(ecx, adr);
1692}
1693
1694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001695void Assembler::fist_s(const Operand& adr) {
1696 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001697 EMIT(0xDB);
1698 emit_operand(edx, adr);
1699}
1700
1701
1702void Assembler::fistp_d(const Operand& adr) {
1703 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001704 EMIT(0xDF);
1705 emit_operand(edi, adr);
1706}
1707
1708
1709void Assembler::fabs() {
1710 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001711 EMIT(0xD9);
1712 EMIT(0xE1);
1713}
1714
1715
1716void Assembler::fchs() {
1717 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001718 EMIT(0xD9);
1719 EMIT(0xE0);
1720}
1721
1722
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001723void Assembler::fcos() {
1724 EnsureSpace ensure_space(this);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001725 EMIT(0xD9);
1726 EMIT(0xFF);
1727}
1728
1729
1730void Assembler::fsin() {
1731 EnsureSpace ensure_space(this);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001732 EMIT(0xD9);
1733 EMIT(0xFE);
1734}
1735
1736
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001737void Assembler::fptan() {
1738 EnsureSpace ensure_space(this);
1739 EMIT(0xD9);
1740 EMIT(0xF2);
1741}
1742
1743
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001744void Assembler::fyl2x() {
1745 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746 EMIT(0xD9);
1747 EMIT(0xF1);
1748}
1749
1750
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001751void Assembler::f2xm1() {
1752 EnsureSpace ensure_space(this);
1753 EMIT(0xD9);
1754 EMIT(0xF0);
1755}
1756
1757
1758void Assembler::fscale() {
1759 EnsureSpace ensure_space(this);
1760 EMIT(0xD9);
1761 EMIT(0xFD);
1762}
1763
1764
1765void Assembler::fninit() {
1766 EnsureSpace ensure_space(this);
1767 EMIT(0xDB);
1768 EMIT(0xE3);
1769}
1770
1771
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001772void Assembler::fadd(int i) {
1773 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001774 emit_farith(0xDC, 0xC0, i);
1775}
1776
1777
1778void Assembler::fsub(int i) {
1779 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001780 emit_farith(0xDC, 0xE8, i);
1781}
1782
1783
1784void Assembler::fisub_s(const Operand& adr) {
1785 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001786 EMIT(0xDA);
1787 emit_operand(esp, adr);
1788}
1789
1790
danno@chromium.org169691d2013-07-15 08:01:13 +00001791void Assembler::fmul_i(int i) {
1792 EnsureSpace ensure_space(this);
1793 emit_farith(0xD8, 0xC8, i);
1794}
1795
1796
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001797void Assembler::fmul(int i) {
1798 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 emit_farith(0xDC, 0xC8, i);
1800}
1801
1802
1803void Assembler::fdiv(int i) {
1804 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805 emit_farith(0xDC, 0xF8, i);
1806}
1807
1808
1809void Assembler::faddp(int i) {
1810 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001811 emit_farith(0xDE, 0xC0, i);
1812}
1813
1814
1815void Assembler::fsubp(int i) {
1816 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817 emit_farith(0xDE, 0xE8, i);
1818}
1819
1820
1821void Assembler::fsubrp(int i) {
1822 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001823 emit_farith(0xDE, 0xE0, i);
1824}
1825
1826
1827void Assembler::fmulp(int i) {
1828 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829 emit_farith(0xDE, 0xC8, i);
1830}
1831
1832
1833void Assembler::fdivp(int i) {
1834 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001835 emit_farith(0xDE, 0xF8, i);
1836}
1837
1838
1839void Assembler::fprem() {
1840 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001841 EMIT(0xD9);
1842 EMIT(0xF8);
1843}
1844
1845
1846void Assembler::fprem1() {
1847 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001848 EMIT(0xD9);
1849 EMIT(0xF5);
1850}
1851
1852
1853void Assembler::fxch(int i) {
1854 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001855 emit_farith(0xD9, 0xC8, i);
1856}
1857
1858
1859void Assembler::fincstp() {
1860 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001861 EMIT(0xD9);
1862 EMIT(0xF7);
1863}
1864
1865
1866void Assembler::ffree(int i) {
1867 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001868 emit_farith(0xDD, 0xC0, i);
1869}
1870
1871
1872void Assembler::ftst() {
1873 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874 EMIT(0xD9);
1875 EMIT(0xE4);
1876}
1877
1878
1879void Assembler::fucomp(int i) {
1880 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001881 emit_farith(0xDD, 0xE8, i);
1882}
1883
1884
1885void Assembler::fucompp() {
1886 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001887 EMIT(0xDA);
1888 EMIT(0xE9);
1889}
1890
1891
ager@chromium.org3811b432009-10-28 14:53:37 +00001892void Assembler::fucomi(int i) {
1893 EnsureSpace ensure_space(this);
ager@chromium.org3811b432009-10-28 14:53:37 +00001894 EMIT(0xDB);
1895 EMIT(0xE8 + i);
1896}
1897
1898
1899void Assembler::fucomip() {
1900 EnsureSpace ensure_space(this);
ager@chromium.org3811b432009-10-28 14:53:37 +00001901 EMIT(0xDF);
1902 EMIT(0xE9);
1903}
1904
1905
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001906void Assembler::fcompp() {
1907 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908 EMIT(0xDE);
1909 EMIT(0xD9);
1910}
1911
1912
1913void Assembler::fnstsw_ax() {
1914 EnsureSpace ensure_space(this);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001915 EMIT(0xDF);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001916 EMIT(0xE0);
1917}
1918
1919
1920void Assembler::fwait() {
1921 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001922 EMIT(0x9B);
1923}
1924
1925
1926void Assembler::frndint() {
1927 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001928 EMIT(0xD9);
1929 EMIT(0xFC);
1930}
1931
1932
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001933void Assembler::fnclex() {
1934 EnsureSpace ensure_space(this);
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001935 EMIT(0xDB);
1936 EMIT(0xE2);
1937}
1938
1939
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001940void Assembler::sahf() {
1941 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942 EMIT(0x9E);
1943}
1944
1945
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001946void Assembler::setcc(Condition cc, Register reg) {
1947 ASSERT(reg.is_byte_register());
1948 EnsureSpace ensure_space(this);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001949 EMIT(0x0F);
1950 EMIT(0x90 | cc);
1951 EMIT(0xC0 | reg.code());
1952}
1953
1954
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001955void Assembler::cvttss2si(Register dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001956 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001957 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001958 EMIT(0xF3);
1959 EMIT(0x0F);
1960 EMIT(0x2C);
1961 emit_operand(dst, src);
1962}
1963
1964
1965void Assembler::cvttsd2si(Register dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001966 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001967 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001968 EMIT(0xF2);
1969 EMIT(0x0F);
1970 EMIT(0x2C);
1971 emit_operand(dst, src);
1972}
1973
1974
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001975void Assembler::cvtsd2si(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001976 ASSERT(IsEnabled(SSE2));
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001977 EnsureSpace ensure_space(this);
1978 EMIT(0xF2);
1979 EMIT(0x0F);
1980 EMIT(0x2D);
1981 emit_sse_operand(dst, src);
1982}
1983
1984
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001985void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001986 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001987 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001988 EMIT(0xF2);
1989 EMIT(0x0F);
1990 EMIT(0x2A);
1991 emit_sse_operand(dst, src);
1992}
1993
1994
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001995void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001996 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001997 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001998 EMIT(0xF3);
1999 EMIT(0x0F);
2000 EMIT(0x5A);
2001 emit_sse_operand(dst, src);
2002}
2003
2004
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002005void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002006 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002007 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002008 EMIT(0xF2);
2009 EMIT(0x0F);
2010 EMIT(0x5A);
2011 emit_sse_operand(dst, src);
2012}
2013
2014
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002015void Assembler::addsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002016 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002017 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002018 EMIT(0xF2);
2019 EMIT(0x0F);
2020 EMIT(0x58);
2021 emit_sse_operand(dst, src);
2022}
2023
2024
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002025void Assembler::addsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002026 ASSERT(IsEnabled(SSE2));
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002027 EnsureSpace ensure_space(this);
2028 EMIT(0xF2);
2029 EMIT(0x0F);
2030 EMIT(0x58);
2031 emit_sse_operand(dst, src);
2032}
2033
2034
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002035void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002036 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002037 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038 EMIT(0xF2);
2039 EMIT(0x0F);
2040 EMIT(0x59);
2041 emit_sse_operand(dst, src);
2042}
2043
2044
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002045void Assembler::mulsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002046 ASSERT(IsEnabled(SSE2));
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002047 EnsureSpace ensure_space(this);
2048 EMIT(0xF2);
2049 EMIT(0x0F);
2050 EMIT(0x59);
2051 emit_sse_operand(dst, src);
2052}
2053
2054
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055void Assembler::subsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002056 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002057 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002058 EMIT(0xF2);
2059 EMIT(0x0F);
2060 EMIT(0x5C);
2061 emit_sse_operand(dst, src);
2062}
2063
2064
2065void Assembler::divsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002066 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002067 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002068 EMIT(0xF2);
2069 EMIT(0x0F);
2070 EMIT(0x5E);
2071 emit_sse_operand(dst, src);
2072}
2073
2074
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002075void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002076 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002077 EnsureSpace ensure_space(this);
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002078 EMIT(0x66);
2079 EMIT(0x0F);
2080 EMIT(0x57);
2081 emit_sse_operand(dst, src);
2082}
2083
2084
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002085void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2086 EnsureSpace ensure_space(this);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002087 EMIT(0x0F);
2088 EMIT(0x57);
2089 emit_sse_operand(dst, src);
2090}
2091
2092
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002093void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2094 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002095 EMIT(0xF2);
2096 EMIT(0x0F);
2097 EMIT(0x51);
2098 emit_sse_operand(dst, src);
2099}
2100
2101
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002102void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2103 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002104 EMIT(0x66);
2105 EMIT(0x0F);
2106 EMIT(0x54);
2107 emit_sse_operand(dst, src);
2108}
2109
2110
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00002111void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2112 EnsureSpace ensure_space(this);
2113 EMIT(0x66);
2114 EMIT(0x0F);
2115 EMIT(0x56);
2116 emit_sse_operand(dst, src);
2117}
2118
2119
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002120void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002121 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002122 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002123 EMIT(0x66);
2124 EMIT(0x0F);
2125 EMIT(0x2E);
2126 emit_sse_operand(dst, src);
2127}
2128
2129
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002130void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002131 ASSERT(IsEnabled(SSE2));
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002132 EnsureSpace ensure_space(this);
2133 EMIT(0x66);
2134 EMIT(0x0F);
2135 EMIT(0x2E);
2136 emit_sse_operand(dst, src);
2137}
2138
2139
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002140void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002141 ASSERT(IsEnabled(SSE4_1));
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002142 EnsureSpace ensure_space(this);
2143 EMIT(0x66);
2144 EMIT(0x0F);
2145 EMIT(0x3A);
2146 EMIT(0x0B);
2147 emit_sse_operand(dst, src);
2148 // Mask precision exeption.
2149 EMIT(static_cast<byte>(mode) | 0x8);
2150}
2151
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00002152
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002153void Assembler::movmskpd(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002154 ASSERT(IsEnabled(SSE2));
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002155 EnsureSpace ensure_space(this);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002156 EMIT(0x66);
2157 EMIT(0x0F);
2158 EMIT(0x50);
2159 emit_sse_operand(dst, src);
2160}
2161
2162
ulan@chromium.org4121f232012-12-27 15:57:11 +00002163void Assembler::movmskps(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002164 ASSERT(IsEnabled(SSE2));
ulan@chromium.org4121f232012-12-27 15:57:11 +00002165 EnsureSpace ensure_space(this);
2166 EMIT(0x0F);
2167 EMIT(0x50);
2168 emit_sse_operand(dst, src);
2169}
2170
2171
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002172void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002173 ASSERT(IsEnabled(SSE2));
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002174 EnsureSpace ensure_space(this);
2175 EMIT(0x66);
2176 EMIT(0x0F);
2177 EMIT(0x76);
2178 emit_sse_operand(dst, src);
2179}
2180
2181
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002182void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002183 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002184 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002185 EMIT(0xF2);
2186 EMIT(0x0F);
2187 EMIT(0xC2);
2188 emit_sse_operand(dst, src);
2189 EMIT(1); // LT == 1
2190}
2191
2192
2193void Assembler::movaps(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002194 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002195 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002196 EMIT(0x0F);
2197 EMIT(0x28);
2198 emit_sse_operand(dst, src);
2199}
2200
2201
2202void Assembler::movdqa(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002203 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002204 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002205 EMIT(0x66);
2206 EMIT(0x0F);
2207 EMIT(0x7F);
2208 emit_sse_operand(src, dst);
2209}
2210
2211
2212void Assembler::movdqa(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002213 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002214 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002215 EMIT(0x66);
2216 EMIT(0x0F);
2217 EMIT(0x6F);
2218 emit_sse_operand(dst, src);
2219}
2220
2221
2222void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002223 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002224 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002225 EMIT(0xF3);
2226 EMIT(0x0F);
2227 EMIT(0x7F);
2228 emit_sse_operand(src, dst);
2229}
2230
2231
2232void Assembler::movdqu(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002233 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002234 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002235 EMIT(0xF3);
2236 EMIT(0x0F);
2237 EMIT(0x6F);
2238 emit_sse_operand(dst, src);
2239}
2240
2241
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002242void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002243 ASSERT(IsEnabled(SSE4_1));
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002244 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002245 EMIT(0x66);
2246 EMIT(0x0F);
2247 EMIT(0x38);
2248 EMIT(0x2A);
2249 emit_sse_operand(dst, src);
2250}
2251
2252
2253void Assembler::movntdq(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002254 ASSERT(IsEnabled(SSE2));
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002255 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002256 EMIT(0x66);
2257 EMIT(0x0F);
2258 EMIT(0xE7);
2259 emit_sse_operand(src, dst);
2260}
2261
2262
2263void Assembler::prefetch(const Operand& src, int level) {
2264 ASSERT(is_uint2(level));
2265 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002266 EMIT(0x0F);
2267 EMIT(0x18);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002268 // Emit hint number in Reg position of RegR/M.
2269 XMMRegister code = XMMRegister::from_code(level);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002270 emit_sse_operand(code, src);
2271}
2272
2273
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274void Assembler::movdbl(XMMRegister dst, const Operand& src) {
2275 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002276 movsd(dst, src);
2277}
2278
2279
2280void Assembler::movdbl(const Operand& dst, XMMRegister src) {
2281 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002282 movsd(dst, src);
2283}
2284
2285
2286void Assembler::movsd(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002287 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002288 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002289 EMIT(0xF2); // double
2290 EMIT(0x0F);
2291 EMIT(0x11); // store
2292 emit_sse_operand(src, dst);
2293}
2294
2295
2296void Assembler::movsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002297 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299 EMIT(0xF2); // double
2300 EMIT(0x0F);
2301 EMIT(0x10); // load
2302 emit_sse_operand(dst, src);
2303}
2304
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002305
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002306void Assembler::movsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002307 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002308 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002309 EMIT(0xF2);
2310 EMIT(0x0F);
2311 EMIT(0x10);
2312 emit_sse_operand(dst, src);
2313}
2314
2315
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002316void Assembler::movss(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002317 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002318 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002319 EMIT(0xF3); // float
2320 EMIT(0x0F);
2321 EMIT(0x11); // store
2322 emit_sse_operand(src, dst);
2323}
2324
2325
2326void Assembler::movss(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002327 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002328 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002329 EMIT(0xF3); // float
2330 EMIT(0x0F);
2331 EMIT(0x10); // load
2332 emit_sse_operand(dst, src);
2333}
2334
2335
2336void Assembler::movss(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002337 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002338 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002339 EMIT(0xF3);
2340 EMIT(0x0F);
2341 EMIT(0x10);
2342 emit_sse_operand(dst, src);
2343}
2344
2345
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002346void Assembler::movd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002347 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002348 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002349 EMIT(0x66);
2350 EMIT(0x0F);
2351 EMIT(0x6E);
2352 emit_sse_operand(dst, src);
2353}
2354
2355
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002356void Assembler::movd(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002357 ASSERT(IsEnabled(SSE2));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002358 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002359 EMIT(0x66);
2360 EMIT(0x0F);
2361 EMIT(0x7E);
2362 emit_sse_operand(src, dst);
2363}
2364
2365
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002366void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
ulan@chromium.org837a67e2013-06-11 15:39:48 +00002367 ASSERT(IsEnabled(SSE4_1));
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002368 ASSERT(is_uint8(imm8));
2369 EnsureSpace ensure_space(this);
2370 EMIT(0x66);
2371 EMIT(0x0F);
2372 EMIT(0x3A);
2373 EMIT(0x17);
2374 emit_sse_operand(dst, src);
2375 EMIT(imm8);
2376}
2377
2378
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002379void Assembler::pand(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002380 ASSERT(IsEnabled(SSE2));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002381 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002382 EMIT(0x66);
2383 EMIT(0x0F);
2384 EMIT(0xDB);
2385 emit_sse_operand(dst, src);
2386}
2387
2388
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002389void Assembler::pxor(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002390 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002391 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002392 EMIT(0x66);
2393 EMIT(0x0F);
2394 EMIT(0xEF);
2395 emit_sse_operand(dst, src);
2396}
2397
2398
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002399void Assembler::por(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002400 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002401 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002402 EMIT(0x66);
2403 EMIT(0x0F);
2404 EMIT(0xEB);
2405 emit_sse_operand(dst, src);
2406}
2407
2408
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002409void Assembler::ptest(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002410 ASSERT(IsEnabled(SSE4_1));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002411 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002412 EMIT(0x66);
2413 EMIT(0x0F);
2414 EMIT(0x38);
2415 EMIT(0x17);
2416 emit_sse_operand(dst, src);
2417}
2418
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002419
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002420void Assembler::psllq(XMMRegister reg, int8_t shift) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002421 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002422 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002423 EMIT(0x66);
2424 EMIT(0x0F);
2425 EMIT(0x73);
2426 emit_sse_operand(esi, reg); // esi == 6
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002427 EMIT(shift);
2428}
2429
2430
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002431void Assembler::psllq(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002432 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002433 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002434 EMIT(0x66);
2435 EMIT(0x0F);
2436 EMIT(0xF3);
2437 emit_sse_operand(dst, src);
2438}
2439
2440
2441void Assembler::psrlq(XMMRegister reg, int8_t shift) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002442 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002443 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002444 EMIT(0x66);
2445 EMIT(0x0F);
2446 EMIT(0x73);
2447 emit_sse_operand(edx, reg); // edx == 2
2448 EMIT(shift);
2449}
2450
2451
2452void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002453 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002454 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002455 EMIT(0x66);
2456 EMIT(0x0F);
2457 EMIT(0xD3);
2458 emit_sse_operand(dst, src);
2459}
2460
2461
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002462void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002463 ASSERT(IsEnabled(SSE2));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002464 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002465 EMIT(0x66);
2466 EMIT(0x0F);
2467 EMIT(0x70);
2468 emit_sse_operand(dst, src);
2469 EMIT(shuffle);
2470}
2471
2472
2473void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002474 ASSERT(IsEnabled(SSE4_1));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002475 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002476 EMIT(0x66);
2477 EMIT(0x0F);
2478 EMIT(0x3A);
2479 EMIT(0x16);
2480 emit_sse_operand(src, dst);
2481 EMIT(offset);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002482}
2483
2484
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002485void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002486 ASSERT(IsEnabled(SSE4_1));
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002487 EnsureSpace ensure_space(this);
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002488 EMIT(0x66);
2489 EMIT(0x0F);
2490 EMIT(0x3A);
2491 EMIT(0x22);
2492 emit_sse_operand(dst, src);
2493 EMIT(offset);
2494}
2495
2496
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2498 Register ireg = { reg.code() };
2499 emit_operand(ireg, adr);
2500}
2501
2502
2503void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2504 EMIT(0xC0 | dst.code() << 3 | src.code());
2505}
2506
2507
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002508void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2509 EMIT(0xC0 | dst.code() << 3 | src.code());
2510}
2511
2512
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002513void Assembler::Print() {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002514 Disassembler::Decode(isolate(), stdout, buffer_, pc_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002515}
2516
2517
2518void Assembler::RecordJSReturn() {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002519 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002520 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00002521 RecordRelocInfo(RelocInfo::JS_RETURN);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002522}
2523
2524
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002525void Assembler::RecordDebugBreakSlot() {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002526 positions_recorder()->WriteRecordedPositions();
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002527 EnsureSpace ensure_space(this);
2528 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2529}
2530
2531
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002532void Assembler::RecordComment(const char* msg, bool force) {
2533 if (FLAG_code_comments || force) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002534 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00002535 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002536 }
2537}
2538
2539
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002540void Assembler::GrowBuffer() {
ager@chromium.org5c838252010-02-19 08:53:10 +00002541 ASSERT(overflow());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002542 if (!own_buffer_) FATAL("external code buffer is too small");
2543
ager@chromium.org5c838252010-02-19 08:53:10 +00002544 // Compute new buffer size.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002545 CodeDesc desc; // the new buffer
2546 if (buffer_size_ < 4*KB) {
2547 desc.buffer_size = 4*KB;
2548 } else {
2549 desc.buffer_size = 2*buffer_size_;
2550 }
2551 // Some internal data structures overflow for very large buffers,
2552 // they must ensure that kMaximalBufferSize is not too large.
2553 if ((desc.buffer_size > kMaximalBufferSize) ||
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002554 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002555 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2556 }
2557
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002558 // Set up new buffer.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002559 desc.buffer = NewArray<byte>(desc.buffer_size);
2560 desc.instr_size = pc_offset();
2561 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2562
2563 // Clear the buffer in debug mode. Use 'int3' instructions to make
2564 // sure to get into problems if we ever run uninitialized code.
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002565#ifdef DEBUG
2566 memset(desc.buffer, 0xCC, desc.buffer_size);
2567#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002568
ager@chromium.org5c838252010-02-19 08:53:10 +00002569 // Copy the data.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002570 int pc_delta = desc.buffer - buffer_;
2571 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002572 OS::MemMove(desc.buffer, buffer_, desc.instr_size);
2573 OS::MemMove(rc_delta + reloc_info_writer.pos(),
2574 reloc_info_writer.pos(), desc.reloc_size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575
ager@chromium.org5c838252010-02-19 08:53:10 +00002576 // Switch buffers.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002577 if (isolate()->assembler_spare_buffer() == NULL &&
2578 buffer_size_ == kMinimalBufferSize) {
2579 isolate()->set_assembler_spare_buffer(buffer_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002580 } else {
2581 DeleteArray(buffer_);
2582 }
2583 buffer_ = desc.buffer;
2584 buffer_size_ = desc.buffer_size;
2585 pc_ += pc_delta;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002586 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2587 reloc_info_writer.last_pc() + pc_delta);
2588
ager@chromium.org5c838252010-02-19 08:53:10 +00002589 // Relocate runtime entries.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590 for (RelocIterator it(desc); !it.done(); it.next()) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002591 RelocInfo::Mode rmode = it.rinfo()->rmode();
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00002592 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002593 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2594 if (*p != 0) { // 0 means uninitialized.
2595 *p += pc_delta;
2596 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002597 }
2598 }
2599
2600 ASSERT(!overflow());
2601}
2602
2603
2604void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
2605 ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode
2606 ASSERT(is_uint8(imm8));
2607 ASSERT((op1 & 0x01) == 0); // should be 8bit operation
2608 EMIT(op1);
2609 EMIT(op2 | dst.code());
2610 EMIT(imm8);
2611}
2612
2613
2614void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
2615 ASSERT((0 <= sel) && (sel <= 7));
2616 Register ireg = { sel };
2617 if (x.is_int8()) {
2618 EMIT(0x83); // using a sign-extended 8-bit immediate.
2619 emit_operand(ireg, dst);
2620 EMIT(x.x_ & 0xFF);
2621 } else if (dst.is_reg(eax)) {
2622 EMIT((sel << 3) | 0x05); // short form if the destination is eax.
2623 emit(x);
2624 } else {
2625 EMIT(0x81); // using a literal 32-bit immediate.
2626 emit_operand(ireg, dst);
2627 emit(x);
2628 }
2629}
2630
2631
2632void Assembler::emit_operand(Register reg, const Operand& adr) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002633 const unsigned length = adr.len_;
2634 ASSERT(length > 0);
2635
2636 // Emit updated ModRM byte containing the given register.
2637 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2638
2639 // Emit the rest of the encoded operand.
2640 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2641 pc_ += length;
2642
2643 // Emit relocation information if necessary.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002644 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002645 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32
2646 RecordRelocInfo(adr.rmode_);
2647 pc_ += sizeof(int32_t);
2648 }
2649}
2650
2651
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002652void Assembler::emit_farith(int b1, int b2, int i) {
2653 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2654 ASSERT(0 <= i && i < 8); // illegal stack offset
2655 EMIT(b1);
2656 EMIT(b2 + i);
2657}
2658
2659
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002660void Assembler::db(uint8_t data) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002661 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002662 EMIT(data);
2663}
2664
2665
2666void Assembler::dd(uint32_t data) {
2667 EnsureSpace ensure_space(this);
2668 emit(data);
ager@chromium.org236ad962008-09-25 09:45:57 +00002669}
2670
2671
2672void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002673 ASSERT(!RelocInfo::IsNone(rmode));
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00002674 // Don't record external references unless the heap will be serialized.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002675 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2676#ifdef DEBUG
2677 if (!Serializer::enabled()) {
2678 Serializer::TooLateToEnableNow();
2679 }
2680#endif
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00002681 if (!Serializer::enabled() && !emit_debug_code()) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002682 return;
2683 }
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00002684 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002685 RelocInfo rinfo(pc_, rmode, data, NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002686 reloc_info_writer.Write(&rinfo);
2687}
2688
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002689
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002690#ifdef GENERATED_CODE_COVERAGE
2691static FILE* coverage_log = NULL;
2692
2693
2694static void InitCoverageLog() {
2695 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
2696 if (file_name != NULL) {
2697 coverage_log = fopen(file_name, "aw+");
2698 }
2699}
2700
2701
2702void LogGeneratedCodeCoverage(const char* file_line) {
2703 const char* return_address = (&file_line)[-1];
2704 char* push_insn = const_cast<char*>(return_address - 12);
2705 push_insn[0] = 0xeb; // Relative branch insn.
2706 push_insn[1] = 13; // Skip over coverage insns.
2707 if (coverage_log != NULL) {
2708 fprintf(coverage_log, "%s\n", file_line);
2709 fflush(coverage_log);
2710 }
2711}
2712
2713#endif
2714
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002715} } // namespace v8::internal
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002716
2717#endif // V8_TARGET_ARCH_IA32