blob: 24c6b9262961a7da2d22cc7f176fdda212360db3 [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;
mvstanton@chromium.org63ea3d22013-10-10 09:24:12 +000056uint64_t CpuFeatures::cross_compile_ = 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000057
58
yangguo@chromium.org003650e2013-01-24 16:31:08 +000059ExternalReference ExternalReference::cpu_features() {
60 ASSERT(CpuFeatures::initialized_);
61 return ExternalReference(&CpuFeatures::supported_);
62}
63
64
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000065int IntelDoubleRegister::NumAllocatableRegisters() {
66 if (CpuFeatures::IsSupported(SSE2)) {
67 return XMMRegister::kNumAllocatableRegisters;
68 } else {
danno@chromium.org169691d2013-07-15 08:01:13 +000069 return X87Register::kNumAllocatableRegisters;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000070 }
71}
72
73
74int IntelDoubleRegister::NumRegisters() {
75 if (CpuFeatures::IsSupported(SSE2)) {
76 return XMMRegister::kNumRegisters;
77 } else {
danno@chromium.org169691d2013-07-15 08:01:13 +000078 return X87Register::kNumRegisters;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000079 }
80}
81
82
83const char* IntelDoubleRegister::AllocationIndexToString(int index) {
84 if (CpuFeatures::IsSupported(SSE2)) {
85 return XMMRegister::AllocationIndexToString(index);
86 } else {
danno@chromium.org169691d2013-07-15 08:01:13 +000087 return X87Register::AllocationIndexToString(index);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000088 }
89}
90
91
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000092// The Probe method needs executable memory, so it uses Heap::CreateCode.
93// Allocation failure is silent and leads to safe default.
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +000094void CpuFeatures::Probe() {
95 ASSERT(!initialized_);
kasperl@chromium.org061ef742009-02-27 12:16:20 +000096 ASSERT(supported_ == 0);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +000097#ifdef DEBUG
98 initialized_ = true;
99#endif
100 if (Serializer::enabled()) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000101 supported_ |= OS::CpuFeaturesImpliedByPlatform();
102 return; // No features if we might serialize.
103 }
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000104
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000105 uint64_t probed_features = 0;
106 CPU cpu;
107 if (cpu.has_sse41()) {
108 probed_features |= static_cast<uint64_t>(1) << SSE4_1;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000109 }
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000110 if (cpu.has_sse3()) {
111 probed_features |= static_cast<uint64_t>(1) << SSE3;
112 }
113 if (cpu.has_sse2()) {
114 probed_features |= static_cast<uint64_t>(1) << SSE2;
115 }
116 if (cpu.has_cmov()) {
117 probed_features |= static_cast<uint64_t>(1) << CMOV;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000118 }
119
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000120 // SAHF must be available in compat/legacy mode.
121 ASSERT(cpu.has_sahf());
122 probed_features |= static_cast<uint64_t>(1) << SAHF;
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000123
ulan@chromium.org750145a2013-03-07 15:14:13 +0000124 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform();
125 supported_ = probed_features | platform_features;
126 found_by_runtime_probing_only_ = probed_features & ~platform_features;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000127}
128
129
130// -----------------------------------------------------------------------------
kasper.lund7276f142008-07-30 08:49:36 +0000131// Implementation of Displacement
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000132
kasper.lund7276f142008-07-30 08:49:36 +0000133void Displacement::init(Label* L, Type type) {
134 ASSERT(!L->is_bound());
135 int next = 0;
136 if (L->is_linked()) {
137 next = L->pos();
138 ASSERT(next > 0); // Displacements must be at positions > 0
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000139 }
kasper.lund7276f142008-07-30 08:49:36 +0000140 // Ensure that we _never_ overflow the next field.
141 ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize));
142 data_ = NextField::encode(next) | TypeField::encode(type);
143}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000144
145
146// -----------------------------------------------------------------------------
147// Implementation of RelocInfo
148
149
150const int RelocInfo::kApplyMask =
ager@chromium.org236ad962008-09-25 09:45:57 +0000151 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +0000152 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000153 1 << RelocInfo::DEBUG_BREAK_SLOT | 1 << RelocInfo::CODE_AGE_SEQUENCE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000154
155
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000156bool RelocInfo::IsCodedSpecially() {
157 // The deserializer needs to know whether a pointer is specially coded. Being
158 // specially coded on IA32 means that it is a relative address, as used by
159 // branch instructions. These are also the ones that need changing when a
160 // code object moves.
161 return (1 << rmode_) & kApplyMask;
162}
163
164
iposva@chromium.org245aa852009-02-10 00:49:54 +0000165void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000166 // Patch the code at the current address with the supplied instructions.
167 for (int i = 0; i < instruction_count; i++) {
168 *(pc_ + i) = *(instructions + i);
169 }
ager@chromium.org4af710e2009-09-15 12:20:11 +0000170
171 // Indicate that code has changed.
172 CPU::FlushICache(pc_, instruction_count);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000173}
174
175
176// Patch the code at the current PC with a call to the target address.
177// Additional guard int3 instructions can be added if required.
iposva@chromium.org245aa852009-02-10 00:49:54 +0000178void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000179 // Call instruction takes up 5 bytes and int3 takes up one byte.
ager@chromium.org4af710e2009-09-15 12:20:11 +0000180 static const int kCallCodeSize = 5;
181 int code_size = kCallCodeSize + guard_bytes;
182
183 // Create a code patcher.
184 CodePatcher patcher(pc_, code_size);
185
186 // Add a label for checking the size of the code used for returning.
187#ifdef DEBUG
188 Label check_codesize;
189 patcher.masm()->bind(&check_codesize);
190#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000191
192 // Patch the code.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000193 patcher.masm()->call(target, RelocInfo::NONE32);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000194
ager@chromium.org4af710e2009-09-15 12:20:11 +0000195 // Check that the size of the code generated is as expected.
196 ASSERT_EQ(kCallCodeSize,
197 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
198
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000199 // Add the requested number of int3 instructions after the call.
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000200 ASSERT_GE(guard_bytes, 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000201 for (int i = 0; i < guard_bytes; i++) {
202 patcher.masm()->int3();
203 }
204}
205
206
207// -----------------------------------------------------------------------------
208// Implementation of Operand
209
ager@chromium.org236ad962008-09-25 09:45:57 +0000210Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211 // [base + disp/r]
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000212 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000213 // [base]
214 set_modrm(0, base);
215 if (base.is(esp)) set_sib(times_1, esp, base);
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000216 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217 // [base + disp8]
218 set_modrm(1, base);
219 if (base.is(esp)) set_sib(times_1, esp, base);
220 set_disp8(disp);
221 } else {
222 // [base + disp/r]
223 set_modrm(2, base);
224 if (base.is(esp)) set_sib(times_1, esp, base);
225 set_dispr(disp, rmode);
226 }
227}
228
229
230Operand::Operand(Register base,
231 Register index,
232 ScaleFactor scale,
233 int32_t disp,
ager@chromium.org236ad962008-09-25 09:45:57 +0000234 RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000235 ASSERT(!index.is(esp)); // illegal addressing mode
236 // [base + index*scale + disp/r]
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000237 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000238 // [base + index*scale]
239 set_modrm(0, esp);
240 set_sib(scale, index, base);
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000241 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000242 // [base + index*scale + disp8]
243 set_modrm(1, esp);
244 set_sib(scale, index, base);
245 set_disp8(disp);
246 } else {
247 // [base + index*scale + disp/r]
248 set_modrm(2, esp);
249 set_sib(scale, index, base);
250 set_dispr(disp, rmode);
251 }
252}
253
254
255Operand::Operand(Register index,
256 ScaleFactor scale,
257 int32_t disp,
ager@chromium.org236ad962008-09-25 09:45:57 +0000258 RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000259 ASSERT(!index.is(esp)); // illegal addressing mode
260 // [index*scale + disp/r]
261 set_modrm(0, esp);
262 set_sib(scale, index, ebp);
263 set_dispr(disp, rmode);
264}
265
266
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000267bool Operand::is_reg(Register reg) const {
268 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only.
269 && ((buf_[0] & 0x07) == reg.code()); // register codes match.
270}
271
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000272
273bool Operand::is_reg_only() const {
274 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only.
275}
276
277
278Register Operand::reg() const {
279 ASSERT(is_reg_only());
280 return Register::from_code(buf_[0] & 0x07);
281}
282
283
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000284// -----------------------------------------------------------------------------
ager@chromium.org5c838252010-02-19 08:53:10 +0000285// Implementation of Assembler.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000286
287// Emit a single byte. Must always be inlined.
288#define EMIT(x) \
289 *pc_++ = (x)
290
291
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000292#ifdef GENERATED_CODE_COVERAGE
293static void InitCoverageLog();
294#endif
295
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000296Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
297 : AssemblerBase(isolate, buffer, buffer_size),
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000298 positions_recorder_(this) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000299 // Clear the buffer in debug mode unless it was provided by the
300 // caller in which case we can't be sure it's okay to overwrite
301 // existing code in it; see CodePatcher::CodePatcher(...).
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000302#ifdef DEBUG
303 if (own_buffer_) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000304 memset(buffer_, 0xCC, buffer_size_); // int3
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000305 }
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000306#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000307
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000308 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000309
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000310#ifdef GENERATED_CODE_COVERAGE
311 InitCoverageLog();
312#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000313}
314
315
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000316void Assembler::GetCode(CodeDesc* desc) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000317 // Finalize code (at this point overflow() may be true, but the gap ensures
318 // that we are still not overlapping instructions and relocation info).
319 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000320 // Set up code descriptor.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000321 desc->buffer = buffer_;
322 desc->buffer_size = buffer_size_;
323 desc->instr_size = pc_offset();
324 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000325 desc->origin = this;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000326}
327
328
329void Assembler::Align(int m) {
330 ASSERT(IsPowerOf2(m));
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000331 int mask = m - 1;
332 int addr = pc_offset();
333 Nop((m - (addr & mask)) & mask);
334}
335
336
337bool Assembler::IsNop(Address addr) {
338 Address a = addr;
339 while (*a == 0x66) a++;
340 if (*a == 0x90) return true;
341 if (a[0] == 0xf && a[1] == 0x1f) return true;
342 return false;
343}
344
345
346void Assembler::Nop(int bytes) {
347 EnsureSpace ensure_space(this);
348
349 if (!CpuFeatures::IsSupported(SSE2)) {
350 // Older CPUs that do not support SSE2 may not support multibyte NOP
351 // instructions.
352 for (; bytes > 0; bytes--) {
353 EMIT(0x90);
354 }
355 return;
356 }
357
358 // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
359 while (bytes > 0) {
360 switch (bytes) {
361 case 2:
362 EMIT(0x66);
363 case 1:
364 EMIT(0x90);
365 return;
366 case 3:
367 EMIT(0xf);
368 EMIT(0x1f);
369 EMIT(0);
370 return;
371 case 4:
372 EMIT(0xf);
373 EMIT(0x1f);
374 EMIT(0x40);
375 EMIT(0);
376 return;
377 case 6:
378 EMIT(0x66);
379 case 5:
380 EMIT(0xf);
381 EMIT(0x1f);
382 EMIT(0x44);
383 EMIT(0);
384 EMIT(0);
385 return;
386 case 7:
387 EMIT(0xf);
388 EMIT(0x1f);
389 EMIT(0x80);
390 EMIT(0);
391 EMIT(0);
392 EMIT(0);
393 EMIT(0);
394 return;
395 default:
396 case 11:
397 EMIT(0x66);
398 bytes--;
399 case 10:
400 EMIT(0x66);
401 bytes--;
402 case 9:
403 EMIT(0x66);
404 bytes--;
405 case 8:
406 EMIT(0xf);
407 EMIT(0x1f);
408 EMIT(0x84);
409 EMIT(0);
410 EMIT(0);
411 EMIT(0);
412 EMIT(0);
413 EMIT(0);
414 bytes -= 8;
415 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000416 }
417}
418
419
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000420void Assembler::CodeTargetAlign() {
421 Align(16); // Preferred alignment of jump targets on ia32.
422}
423
424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000425void Assembler::cpuid() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000426 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000427 EMIT(0x0F);
428 EMIT(0xA2);
429}
430
431
432void Assembler::pushad() {
433 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000434 EMIT(0x60);
435}
436
437
438void Assembler::popad() {
439 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000440 EMIT(0x61);
441}
442
443
444void Assembler::pushfd() {
445 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000446 EMIT(0x9C);
447}
448
449
450void Assembler::popfd() {
451 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000452 EMIT(0x9D);
453}
454
455
456void Assembler::push(const Immediate& x) {
457 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000458 if (x.is_int8()) {
459 EMIT(0x6a);
460 EMIT(x.x_);
461 } else {
462 EMIT(0x68);
463 emit(x);
464 }
465}
466
467
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000468void Assembler::push_imm32(int32_t imm32) {
469 EnsureSpace ensure_space(this);
470 EMIT(0x68);
471 emit(imm32);
472}
473
474
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000475void Assembler::push(Register src) {
476 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477 EMIT(0x50 | src.code());
478}
479
480
481void Assembler::push(const Operand& src) {
482 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000483 EMIT(0xFF);
484 emit_operand(esi, src);
485}
486
487
488void Assembler::pop(Register dst) {
489 ASSERT(reloc_info_writer.last_pc() != NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000490 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000491 EMIT(0x58 | dst.code());
492}
493
494
495void Assembler::pop(const Operand& dst) {
496 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000497 EMIT(0x8F);
498 emit_operand(eax, dst);
499}
500
501
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000502void Assembler::enter(const Immediate& size) {
503 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000504 EMIT(0xC8);
505 emit_w(size);
506 EMIT(0);
507}
508
509
510void Assembler::leave() {
511 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000512 EMIT(0xC9);
513}
514
515
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000516void Assembler::mov_b(Register dst, const Operand& src) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000517 CHECK(dst.is_byte_register());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000518 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000519 EMIT(0x8A);
520 emit_operand(dst, src);
521}
522
523
524void Assembler::mov_b(const Operand& dst, int8_t imm8) {
525 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000526 EMIT(0xC6);
527 emit_operand(eax, dst);
528 EMIT(imm8);
529}
530
531
532void Assembler::mov_b(const Operand& dst, Register src) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000533 CHECK(src.is_byte_register());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000534 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000535 EMIT(0x88);
536 emit_operand(src, dst);
537}
538
539
540void Assembler::mov_w(Register dst, const Operand& src) {
541 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542 EMIT(0x66);
543 EMIT(0x8B);
544 emit_operand(dst, src);
545}
546
547
548void Assembler::mov_w(const Operand& dst, Register src) {
549 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000550 EMIT(0x66);
551 EMIT(0x89);
552 emit_operand(src, dst);
553}
554
555
machenbach@chromium.orge8412be2013-11-08 10:23:52 +0000556void Assembler::mov_w(const Operand& dst, int16_t imm16) {
557 EnsureSpace ensure_space(this);
558 EMIT(0x66);
559 EMIT(0xC7);
560 emit_operand(eax, dst);
561 EMIT(static_cast<int8_t>(imm16 & 0xff));
562 EMIT(static_cast<int8_t>(imm16 >> 8));
563}
564
565
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000566void Assembler::mov(Register dst, int32_t imm32) {
567 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568 EMIT(0xB8 | dst.code());
569 emit(imm32);
570}
571
572
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000573void Assembler::mov(Register dst, const Immediate& x) {
574 EnsureSpace ensure_space(this);
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000575 EMIT(0xB8 | dst.code());
576 emit(x);
577}
578
579
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000580void Assembler::mov(Register dst, Handle<Object> handle) {
581 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000582 EMIT(0xB8 | dst.code());
583 emit(handle);
584}
585
586
587void Assembler::mov(Register dst, const Operand& src) {
588 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000589 EMIT(0x8B);
590 emit_operand(dst, src);
591}
592
593
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000594void Assembler::mov(Register dst, Register src) {
595 EnsureSpace ensure_space(this);
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000596 EMIT(0x89);
597 EMIT(0xC0 | src.code() << 3 | dst.code());
598}
599
600
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000601void Assembler::mov(const Operand& dst, const Immediate& x) {
602 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000603 EMIT(0xC7);
604 emit_operand(eax, dst);
605 emit(x);
606}
607
608
609void Assembler::mov(const Operand& dst, Handle<Object> handle) {
610 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000611 EMIT(0xC7);
612 emit_operand(eax, dst);
613 emit(handle);
614}
615
616
617void Assembler::mov(const Operand& dst, Register src) {
618 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000619 EMIT(0x89);
620 emit_operand(src, dst);
621}
622
623
624void Assembler::movsx_b(Register dst, const Operand& src) {
625 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626 EMIT(0x0F);
627 EMIT(0xBE);
628 emit_operand(dst, src);
629}
630
631
632void Assembler::movsx_w(Register dst, const Operand& src) {
633 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634 EMIT(0x0F);
635 EMIT(0xBF);
636 emit_operand(dst, src);
637}
638
639
640void Assembler::movzx_b(Register dst, const Operand& src) {
641 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000642 EMIT(0x0F);
643 EMIT(0xB6);
644 emit_operand(dst, src);
645}
646
647
648void Assembler::movzx_w(Register dst, const Operand& src) {
649 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650 EMIT(0x0F);
651 EMIT(0xB7);
652 emit_operand(dst, src);
653}
654
655
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000656void Assembler::cmov(Condition cc, Register dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000657 ASSERT(IsEnabled(CMOV));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000658 EnsureSpace ensure_space(this);
ager@chromium.org5c838252010-02-19 08:53:10 +0000659 // Opcode: 0f 40 + cc /r.
ager@chromium.org4af710e2009-09-15 12:20:11 +0000660 EMIT(0x0F);
661 EMIT(0x40 + cc);
662 emit_operand(dst, src);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663}
664
665
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000666void Assembler::cld() {
667 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000668 EMIT(0xFC);
669}
670
671
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000672void Assembler::rep_movs() {
673 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000674 EMIT(0xF3);
675 EMIT(0xA5);
676}
677
678
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000679void Assembler::rep_stos() {
680 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000681 EMIT(0xF3);
682 EMIT(0xAB);
683}
684
685
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000686void Assembler::stos() {
687 EnsureSpace ensure_space(this);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000688 EMIT(0xAB);
689}
690
691
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000692void Assembler::xchg(Register dst, Register src) {
693 EnsureSpace ensure_space(this);
ager@chromium.org5c838252010-02-19 08:53:10 +0000694 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding.
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000695 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
696 } else {
697 EMIT(0x87);
698 EMIT(0xC0 | src.code() << 3 | dst.code());
699 }
700}
701
702
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000703void Assembler::adc(Register dst, int32_t imm32) {
704 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000705 emit_arith(2, Operand(dst), Immediate(imm32));
706}
707
708
709void Assembler::adc(Register dst, const Operand& src) {
710 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000711 EMIT(0x13);
712 emit_operand(dst, src);
713}
714
715
716void Assembler::add(Register dst, const Operand& src) {
717 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000718 EMIT(0x03);
719 emit_operand(dst, src);
720}
721
722
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000723void Assembler::add(const Operand& dst, Register src) {
724 EnsureSpace ensure_space(this);
725 EMIT(0x01);
726 emit_operand(src, dst);
727}
728
729
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000730void Assembler::add(const Operand& dst, const Immediate& x) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000731 ASSERT(reloc_info_writer.last_pc() != NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000732 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733 emit_arith(0, dst, x);
734}
735
736
737void Assembler::and_(Register dst, int32_t imm32) {
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +0000738 and_(dst, Immediate(imm32));
739}
740
741
742void Assembler::and_(Register dst, const Immediate& x) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000743 EnsureSpace ensure_space(this);
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +0000744 emit_arith(4, Operand(dst), x);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745}
746
747
748void Assembler::and_(Register dst, const Operand& src) {
749 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000750 EMIT(0x23);
751 emit_operand(dst, src);
752}
753
754
755void Assembler::and_(const Operand& dst, const Immediate& x) {
756 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757 emit_arith(4, dst, x);
758}
759
760
761void Assembler::and_(const Operand& dst, Register src) {
762 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000763 EMIT(0x21);
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000764 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765}
766
767
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000768void Assembler::cmpb(const Operand& op, int8_t imm8) {
769 EnsureSpace ensure_space(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000770 if (op.is_reg(eax)) {
771 EMIT(0x3C);
772 } else {
773 EMIT(0x80);
774 emit_operand(edi, op); // edi == 7
775 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000776 EMIT(imm8);
777}
778
779
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000780void Assembler::cmpb(const Operand& op, Register reg) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000781 CHECK(reg.is_byte_register());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000782 EnsureSpace ensure_space(this);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000783 EMIT(0x38);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000784 emit_operand(reg, op);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000785}
786
787
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000788void Assembler::cmpb(Register reg, const Operand& op) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000789 CHECK(reg.is_byte_register());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000790 EnsureSpace ensure_space(this);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000791 EMIT(0x3A);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000792 emit_operand(reg, op);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000793}
794
795
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000796void Assembler::cmpw(const Operand& op, Immediate imm16) {
797 ASSERT(imm16.is_int16());
798 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000799 EMIT(0x66);
800 EMIT(0x81);
801 emit_operand(edi, op);
802 emit_w(imm16);
803}
804
805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000806void Assembler::cmp(Register reg, int32_t imm32) {
807 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000808 emit_arith(7, Operand(reg), Immediate(imm32));
809}
810
811
812void Assembler::cmp(Register reg, Handle<Object> handle) {
813 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814 emit_arith(7, Operand(reg), Immediate(handle));
815}
816
817
818void Assembler::cmp(Register reg, const Operand& op) {
819 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000820 EMIT(0x3B);
821 emit_operand(reg, op);
822}
823
824
825void Assembler::cmp(const Operand& op, const Immediate& imm) {
826 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000827 emit_arith(7, op, imm);
828}
829
830
ager@chromium.org4af710e2009-09-15 12:20:11 +0000831void Assembler::cmp(const Operand& op, Handle<Object> handle) {
832 EnsureSpace ensure_space(this);
ager@chromium.org4af710e2009-09-15 12:20:11 +0000833 emit_arith(7, op, Immediate(handle));
834}
835
836
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000837void Assembler::cmpb_al(const Operand& op) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000838 EnsureSpace ensure_space(this);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000839 EMIT(0x38); // CMP r/m8, r8
840 emit_operand(eax, op); // eax has same code as register al.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000841}
842
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000843
844void Assembler::cmpw_ax(const Operand& op) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000845 EnsureSpace ensure_space(this);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000846 EMIT(0x66);
847 EMIT(0x39); // CMP r/m16, r16
848 emit_operand(eax, op); // eax has same code as register ax.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000849}
850
851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000852void Assembler::dec_b(Register dst) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000853 CHECK(dst.is_byte_register());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000854 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000855 EMIT(0xFE);
856 EMIT(0xC8 | dst.code());
857}
858
859
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000860void Assembler::dec_b(const Operand& dst) {
861 EnsureSpace ensure_space(this);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000862 EMIT(0xFE);
863 emit_operand(ecx, dst);
864}
865
866
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000867void Assembler::dec(Register dst) {
868 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000869 EMIT(0x48 | dst.code());
870}
871
872
873void Assembler::dec(const Operand& dst) {
874 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000875 EMIT(0xFF);
876 emit_operand(ecx, dst);
877}
878
879
880void Assembler::cdq() {
881 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000882 EMIT(0x99);
883}
884
885
886void Assembler::idiv(Register src) {
887 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000888 EMIT(0xF7);
889 EMIT(0xF8 | src.code());
890}
891
892
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000893void Assembler::imul(Register reg) {
894 EnsureSpace ensure_space(this);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000895 EMIT(0xF7);
896 EMIT(0xE8 | reg.code());
897}
898
899
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000900void Assembler::imul(Register dst, const Operand& src) {
901 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000902 EMIT(0x0F);
903 EMIT(0xAF);
904 emit_operand(dst, src);
905}
906
907
908void Assembler::imul(Register dst, Register src, int32_t imm32) {
909 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910 if (is_int8(imm32)) {
911 EMIT(0x6B);
912 EMIT(0xC0 | dst.code() << 3 | src.code());
913 EMIT(imm32);
914 } else {
915 EMIT(0x69);
916 EMIT(0xC0 | dst.code() << 3 | src.code());
917 emit(imm32);
918 }
919}
920
921
922void Assembler::inc(Register dst) {
923 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000924 EMIT(0x40 | dst.code());
925}
926
927
928void Assembler::inc(const Operand& dst) {
929 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930 EMIT(0xFF);
931 emit_operand(eax, dst);
932}
933
934
935void Assembler::lea(Register dst, const Operand& src) {
936 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937 EMIT(0x8D);
938 emit_operand(dst, src);
939}
940
941
942void Assembler::mul(Register src) {
943 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000944 EMIT(0xF7);
945 EMIT(0xE0 | src.code());
946}
947
948
949void Assembler::neg(Register dst) {
950 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000951 EMIT(0xF7);
952 EMIT(0xD8 | dst.code());
953}
954
955
956void Assembler::not_(Register dst) {
957 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958 EMIT(0xF7);
959 EMIT(0xD0 | dst.code());
960}
961
962
963void Assembler::or_(Register dst, int32_t imm32) {
964 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000965 emit_arith(1, Operand(dst), Immediate(imm32));
966}
967
968
969void Assembler::or_(Register dst, const Operand& src) {
970 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000971 EMIT(0x0B);
972 emit_operand(dst, src);
973}
974
975
976void Assembler::or_(const Operand& dst, const Immediate& x) {
977 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000978 emit_arith(1, dst, x);
979}
980
981
982void Assembler::or_(const Operand& dst, Register src) {
983 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000984 EMIT(0x09);
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000985 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986}
987
988
989void Assembler::rcl(Register dst, uint8_t imm8) {
990 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000991 ASSERT(is_uint5(imm8)); // illegal shift count
992 if (imm8 == 1) {
993 EMIT(0xD1);
994 EMIT(0xD0 | dst.code());
995 } else {
996 EMIT(0xC1);
997 EMIT(0xD0 | dst.code());
998 EMIT(imm8);
999 }
1000}
1001
1002
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00001003void Assembler::rcr(Register dst, uint8_t imm8) {
1004 EnsureSpace ensure_space(this);
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00001005 ASSERT(is_uint5(imm8)); // illegal shift count
1006 if (imm8 == 1) {
1007 EMIT(0xD1);
1008 EMIT(0xD8 | dst.code());
1009 } else {
1010 EMIT(0xC1);
1011 EMIT(0xD8 | dst.code());
1012 EMIT(imm8);
1013 }
1014}
1015
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001016
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00001017void Assembler::ror(Register dst, uint8_t imm8) {
1018 EnsureSpace ensure_space(this);
1019 ASSERT(is_uint5(imm8)); // illegal shift count
1020 if (imm8 == 1) {
1021 EMIT(0xD1);
1022 EMIT(0xC8 | dst.code());
1023 } else {
1024 EMIT(0xC1);
1025 EMIT(0xC8 | dst.code());
1026 EMIT(imm8);
1027 }
1028}
1029
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001030
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00001031void Assembler::ror_cl(Register dst) {
1032 EnsureSpace ensure_space(this);
1033 EMIT(0xD3);
1034 EMIT(0xC8 | dst.code());
1035}
1036
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00001037
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001038void Assembler::sar(Register dst, uint8_t imm8) {
1039 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001040 ASSERT(is_uint5(imm8)); // illegal shift count
1041 if (imm8 == 1) {
1042 EMIT(0xD1);
1043 EMIT(0xF8 | dst.code());
1044 } else {
1045 EMIT(0xC1);
1046 EMIT(0xF8 | dst.code());
1047 EMIT(imm8);
1048 }
1049}
1050
1051
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001052void Assembler::sar_cl(Register dst) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001054 EMIT(0xD3);
1055 EMIT(0xF8 | dst.code());
1056}
1057
1058
1059void Assembler::sbb(Register dst, const Operand& src) {
1060 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061 EMIT(0x1B);
1062 emit_operand(dst, src);
1063}
1064
1065
1066void Assembler::shld(Register dst, const Operand& src) {
1067 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001068 EMIT(0x0F);
1069 EMIT(0xA5);
1070 emit_operand(dst, src);
1071}
1072
1073
1074void Assembler::shl(Register dst, uint8_t imm8) {
1075 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001076 ASSERT(is_uint5(imm8)); // illegal shift count
1077 if (imm8 == 1) {
1078 EMIT(0xD1);
1079 EMIT(0xE0 | dst.code());
1080 } else {
1081 EMIT(0xC1);
1082 EMIT(0xE0 | dst.code());
1083 EMIT(imm8);
1084 }
1085}
1086
1087
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001088void Assembler::shl_cl(Register dst) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001089 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001090 EMIT(0xD3);
1091 EMIT(0xE0 | dst.code());
1092}
1093
1094
1095void Assembler::shrd(Register dst, const Operand& src) {
1096 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001097 EMIT(0x0F);
1098 EMIT(0xAD);
1099 emit_operand(dst, src);
1100}
1101
1102
1103void Assembler::shr(Register dst, uint8_t imm8) {
1104 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001105 ASSERT(is_uint5(imm8)); // illegal shift count
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001106 if (imm8 == 1) {
1107 EMIT(0xD1);
1108 EMIT(0xE8 | dst.code());
1109 } else {
1110 EMIT(0xC1);
1111 EMIT(0xE8 | dst.code());
1112 EMIT(imm8);
1113 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114}
1115
1116
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001117void Assembler::shr_cl(Register dst) {
1118 EnsureSpace ensure_space(this);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001119 EMIT(0xD3);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001120 EMIT(0xE8 | dst.code());
1121}
1122
1123
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001124void Assembler::sub(const Operand& dst, const Immediate& x) {
1125 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001126 emit_arith(5, dst, x);
1127}
1128
1129
1130void Assembler::sub(Register dst, const Operand& src) {
1131 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001132 EMIT(0x2B);
1133 emit_operand(dst, src);
1134}
1135
1136
1137void Assembler::sub(const Operand& dst, Register src) {
1138 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001139 EMIT(0x29);
ager@chromium.org3bf7b912008-11-17 09:09:45 +00001140 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001141}
1142
1143
1144void Assembler::test(Register reg, const Immediate& imm) {
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00001145 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1146 test_b(reg, imm.x_);
1147 return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001148 }
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00001149
1150 EnsureSpace ensure_space(this);
1151 // This is not using emit_arith because test doesn't support
1152 // sign-extension of 8-bit operands.
1153 if (reg.is(eax)) {
1154 EMIT(0xA9);
1155 } else {
1156 EMIT(0xF7);
1157 EMIT(0xC0 | reg.code());
1158 }
1159 emit(imm);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001160}
1161
1162
1163void Assembler::test(Register reg, const Operand& op) {
1164 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001165 EMIT(0x85);
1166 emit_operand(reg, op);
1167}
1168
1169
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001170void Assembler::test_b(Register reg, const Operand& op) {
yangguo@chromium.org56454712012-02-16 15:33:53 +00001171 CHECK(reg.is_byte_register());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001172 EnsureSpace ensure_space(this);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001173 EMIT(0x84);
1174 emit_operand(reg, op);
1175}
1176
1177
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001178void Assembler::test(const Operand& op, const Immediate& imm) {
danno@chromium.org59400602013-08-13 17:09:37 +00001179 if (op.is_reg_only()) {
1180 test(op.reg(), imm);
1181 return;
1182 }
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00001183 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1184 return test_b(op, imm.x_);
1185 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001186 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001187 EMIT(0xF7);
1188 emit_operand(eax, op);
1189 emit(imm);
1190}
1191
1192
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00001193void Assembler::test_b(Register reg, uint8_t imm8) {
1194 EnsureSpace ensure_space(this);
1195 // Only use test against byte for registers that have a byte
1196 // variant: eax, ebx, ecx, and edx.
1197 if (reg.is(eax)) {
1198 EMIT(0xA8);
1199 EMIT(imm8);
1200 } else if (reg.is_byte_register()) {
1201 emit_arith_b(0xF6, 0xC0, reg, imm8);
1202 } else {
1203 EMIT(0xF7);
1204 EMIT(0xC0 | reg.code());
1205 emit(imm8);
1206 }
1207}
1208
1209
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001210void Assembler::test_b(const Operand& op, uint8_t imm8) {
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +00001211 if (op.is_reg_only()) {
1212 test_b(op.reg(), imm8);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001213 return;
1214 }
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001215 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001216 EMIT(0xF6);
1217 emit_operand(eax, op);
1218 EMIT(imm8);
1219}
1220
1221
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001222void Assembler::xor_(Register dst, int32_t imm32) {
1223 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001224 emit_arith(6, Operand(dst), Immediate(imm32));
1225}
1226
1227
1228void Assembler::xor_(Register dst, const Operand& src) {
1229 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001230 EMIT(0x33);
1231 emit_operand(dst, src);
1232}
1233
1234
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001235void Assembler::xor_(const Operand& dst, Register src) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001236 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001237 EMIT(0x31);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001238 emit_operand(src, dst);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001239}
1240
1241
1242void Assembler::xor_(const Operand& dst, const Immediate& x) {
1243 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244 emit_arith(6, dst, x);
1245}
1246
1247
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001248void Assembler::bt(const Operand& dst, Register src) {
1249 EnsureSpace ensure_space(this);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001250 EMIT(0x0F);
1251 EMIT(0xA3);
1252 emit_operand(src, dst);
1253}
1254
1255
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001256void Assembler::bts(const Operand& dst, Register src) {
1257 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001258 EMIT(0x0F);
1259 EMIT(0xAB);
1260 emit_operand(src, dst);
1261}
1262
1263
1264void Assembler::hlt() {
1265 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001266 EMIT(0xF4);
1267}
1268
1269
1270void Assembler::int3() {
1271 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001272 EMIT(0xCC);
1273}
1274
1275
1276void Assembler::nop() {
1277 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001278 EMIT(0x90);
1279}
1280
1281
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001282void Assembler::ret(int imm16) {
1283 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001284 ASSERT(is_uint16(imm16));
1285 if (imm16 == 0) {
1286 EMIT(0xC3);
1287 } else {
1288 EMIT(0xC2);
1289 EMIT(imm16 & 0xFF);
1290 EMIT((imm16 >> 8) & 0xFF);
1291 }
1292}
1293
1294
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001295// Labels refer to positions in the (to be) generated code.
1296// There are bound, linked, and unused labels.
1297//
1298// Bound labels refer to known positions in the already
1299// generated code. pos() is the position the label refers to.
1300//
1301// Linked labels refer to unknown positions in the code
1302// to be generated; pos() is the position of the 32bit
1303// Displacement of the last instruction using the label.
1304
1305
1306void Assembler::print(Label* L) {
1307 if (L->is_unused()) {
1308 PrintF("unused label\n");
1309 } else if (L->is_bound()) {
1310 PrintF("bound label to %d\n", L->pos());
1311 } else if (L->is_linked()) {
1312 Label l = *L;
1313 PrintF("unbound label");
1314 while (l.is_linked()) {
1315 Displacement disp = disp_at(&l);
1316 PrintF("@ %d ", l.pos());
1317 disp.print();
1318 PrintF("\n");
1319 disp.next(&l);
1320 }
1321 } else {
1322 PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1323 }
1324}
1325
1326
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001327void Assembler::bind_to(Label* L, int pos) {
1328 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001329 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position
1330 while (L->is_linked()) {
1331 Displacement disp = disp_at(L);
1332 int fixup_pos = L->pos();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001333 if (disp.type() == Displacement::CODE_RELATIVE) {
1334 // Relative to Code* heap object pointer.
1335 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1336 } else {
1337 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1338 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
1339 }
ager@chromium.org5c838252010-02-19 08:53:10 +00001340 // Relative address, relative to point after address.
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001341 int imm32 = pos - (fixup_pos + sizeof(int32_t));
1342 long_at_put(fixup_pos, imm32);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001343 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001344 disp.next(L);
1345 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001346 while (L->is_near_linked()) {
1347 int fixup_pos = L->near_link_pos();
1348 int offset_to_next =
1349 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
1350 ASSERT(offset_to_next <= 0);
1351 // Relative address, relative to point after address.
1352 int disp = pos - fixup_pos - sizeof(int8_t);
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00001353 CHECK(0 <= disp && disp <= 127);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001354 set_byte_at(fixup_pos, disp);
1355 if (offset_to_next < 0) {
1356 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1357 } else {
1358 L->UnuseNear();
1359 }
1360 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001361 L->bind_to(pos);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001362}
1363
1364
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001365void Assembler::bind(Label* L) {
1366 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367 ASSERT(!L->is_bound()); // label can only be bound once
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368 bind_to(L, pc_offset());
1369}
1370
1371
1372void Assembler::call(Label* L) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001373 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001374 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001375 if (L->is_bound()) {
1376 const int long_size = 5;
1377 int offs = L->pos() - pc_offset();
1378 ASSERT(offs <= 0);
ager@chromium.org5c838252010-02-19 08:53:10 +00001379 // 1110 1000 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 EMIT(0xE8);
1381 emit(offs - long_size);
1382 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001383 // 1110 1000 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384 EMIT(0xE8);
1385 emit_disp(L, Displacement::OTHER);
1386 }
1387}
1388
1389
ager@chromium.org236ad962008-09-25 09:45:57 +00001390void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001391 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001392 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001393 ASSERT(!RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001394 EMIT(0xE8);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001395 if (RelocInfo::IsRuntimeEntry(rmode)) {
1396 emit(reinterpret_cast<uint32_t>(entry), rmode);
1397 } else {
1398 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1399 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400}
1401
1402
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001403int Assembler::CallSize(const Operand& adr) {
1404 // Call size is 1 (opcode) + adr.len_ (operand).
1405 return 1 + adr.len_;
1406}
1407
1408
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001409void Assembler::call(const Operand& adr) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001410 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001411 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001412 EMIT(0xFF);
1413 emit_operand(edx, adr);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001414}
1415
1416
1417int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1418 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419}
1420
1421
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001422void Assembler::call(Handle<Code> code,
1423 RelocInfo::Mode rmode,
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001424 TypeFeedbackId ast_id) {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00001425 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001426 EnsureSpace ensure_space(this);
bmeurer@chromium.orgc9913f02013-10-24 06:31:36 +00001427 ASSERT(RelocInfo::IsCodeTarget(rmode)
1428 || rmode == RelocInfo::CODE_AGE_SEQUENCE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001429 EMIT(0xE8);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001430 emit(code, rmode, ast_id);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001431}
1432
1433
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001434void Assembler::jmp(Label* L, Label::Distance distance) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436 if (L->is_bound()) {
1437 const int short_size = 2;
1438 const int long_size = 5;
1439 int offs = L->pos() - pc_offset();
1440 ASSERT(offs <= 0);
1441 if (is_int8(offs - short_size)) {
ager@chromium.org5c838252010-02-19 08:53:10 +00001442 // 1110 1011 #8-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001443 EMIT(0xEB);
1444 EMIT((offs - short_size) & 0xFF);
1445 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001446 // 1110 1001 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001447 EMIT(0xE9);
1448 emit(offs - long_size);
1449 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001450 } else if (distance == Label::kNear) {
1451 EMIT(0xEB);
1452 emit_near_disp(L);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001453 } else {
ager@chromium.org5c838252010-02-19 08:53:10 +00001454 // 1110 1001 #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001455 EMIT(0xE9);
1456 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1457 }
1458}
1459
1460
ager@chromium.org236ad962008-09-25 09:45:57 +00001461void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001462 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001463 ASSERT(!RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464 EMIT(0xE9);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001465 if (RelocInfo::IsRuntimeEntry(rmode)) {
1466 emit(reinterpret_cast<uint32_t>(entry), rmode);
1467 } else {
1468 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1469 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001470}
1471
1472
1473void Assembler::jmp(const Operand& adr) {
1474 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001475 EMIT(0xFF);
1476 emit_operand(esp, adr);
1477}
1478
1479
ager@chromium.org236ad962008-09-25 09:45:57 +00001480void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001481 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00001482 ASSERT(RelocInfo::IsCodeTarget(rmode));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001483 EMIT(0xE9);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001484 emit(code, rmode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001485}
1486
1487
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001488void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001489 EnsureSpace ensure_space(this);
danno@chromium.org72204d52012-10-31 10:02:10 +00001490 ASSERT(0 <= cc && static_cast<int>(cc) < 16);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001491 if (L->is_bound()) {
1492 const int short_size = 2;
1493 const int long_size = 6;
1494 int offs = L->pos() - pc_offset();
1495 ASSERT(offs <= 0);
1496 if (is_int8(offs - short_size)) {
1497 // 0111 tttn #8-bit disp
1498 EMIT(0x70 | cc);
1499 EMIT((offs - short_size) & 0xFF);
1500 } else {
1501 // 0000 1111 1000 tttn #32-bit disp
1502 EMIT(0x0F);
1503 EMIT(0x80 | cc);
1504 emit(offs - long_size);
1505 }
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001506 } else if (distance == Label::kNear) {
1507 EMIT(0x70 | cc);
1508 emit_near_disp(L);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001509 } else {
1510 // 0000 1111 1000 tttn #32-bit disp
1511 // Note: could eliminate cond. jumps to this jump if condition
1512 // is the same however, seems to be rather unlikely case.
1513 EMIT(0x0F);
1514 EMIT(0x80 | cc);
1515 emit_disp(L, Displacement::OTHER);
1516 }
1517}
1518
1519
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001520void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521 EnsureSpace ensure_space(this);
danno@chromium.org72204d52012-10-31 10:02:10 +00001522 ASSERT((0 <= cc) && (static_cast<int>(cc) < 16));
ager@chromium.org5c838252010-02-19 08:53:10 +00001523 // 0000 1111 1000 tttn #32-bit disp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001524 EMIT(0x0F);
1525 EMIT(0x80 | cc);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001526 if (RelocInfo::IsRuntimeEntry(rmode)) {
1527 emit(reinterpret_cast<uint32_t>(entry), rmode);
1528 } else {
1529 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1530 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001531}
1532
1533
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001534void Assembler::j(Condition cc, Handle<Code> code) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001535 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001536 // 0000 1111 1000 tttn #32-bit disp
1537 EMIT(0x0F);
1538 EMIT(0x80 | cc);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001539 emit(code, RelocInfo::CODE_TARGET);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001540}
1541
1542
ager@chromium.org5c838252010-02-19 08:53:10 +00001543// FPU instructions.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001544
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001545void Assembler::fld(int i) {
1546 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001547 emit_farith(0xD9, 0xC0, i);
1548}
1549
1550
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001551void Assembler::fstp(int i) {
1552 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001553 emit_farith(0xDD, 0xD8, i);
1554}
1555
1556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001557void Assembler::fld1() {
1558 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001559 EMIT(0xD9);
1560 EMIT(0xE8);
1561}
1562
1563
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001564void Assembler::fldpi() {
1565 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001566 EMIT(0xD9);
1567 EMIT(0xEB);
1568}
1569
1570
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001571void Assembler::fldz() {
1572 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001573 EMIT(0xD9);
1574 EMIT(0xEE);
1575}
1576
1577
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001578void Assembler::fldln2() {
1579 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001580 EMIT(0xD9);
1581 EMIT(0xED);
1582}
1583
1584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585void Assembler::fld_s(const Operand& adr) {
1586 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001587 EMIT(0xD9);
1588 emit_operand(eax, adr);
1589}
1590
1591
1592void Assembler::fld_d(const Operand& adr) {
1593 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594 EMIT(0xDD);
1595 emit_operand(eax, adr);
1596}
1597
1598
1599void Assembler::fstp_s(const Operand& adr) {
1600 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001601 EMIT(0xD9);
1602 emit_operand(ebx, adr);
1603}
1604
1605
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +00001606void Assembler::fst_s(const Operand& adr) {
1607 EnsureSpace ensure_space(this);
1608 EMIT(0xD9);
1609 emit_operand(edx, adr);
1610}
1611
1612
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001613void Assembler::fstp_d(const Operand& adr) {
1614 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001615 EMIT(0xDD);
1616 emit_operand(ebx, adr);
1617}
1618
1619
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001620void Assembler::fst_d(const Operand& adr) {
1621 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001622 EMIT(0xDD);
1623 emit_operand(edx, adr);
1624}
1625
1626
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001627void Assembler::fild_s(const Operand& adr) {
1628 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001629 EMIT(0xDB);
1630 emit_operand(eax, adr);
1631}
1632
1633
1634void Assembler::fild_d(const Operand& adr) {
1635 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001636 EMIT(0xDF);
1637 emit_operand(ebp, adr);
1638}
1639
1640
1641void Assembler::fistp_s(const Operand& adr) {
1642 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001643 EMIT(0xDB);
1644 emit_operand(ebx, adr);
1645}
1646
1647
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001648void Assembler::fisttp_s(const Operand& adr) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001649 ASSERT(IsEnabled(SSE3));
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001650 EnsureSpace ensure_space(this);
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001651 EMIT(0xDB);
1652 emit_operand(ecx, adr);
1653}
1654
1655
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001656void Assembler::fisttp_d(const Operand& adr) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001657 ASSERT(IsEnabled(SSE3));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001658 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001659 EMIT(0xDD);
1660 emit_operand(ecx, adr);
1661}
1662
1663
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001664void Assembler::fist_s(const Operand& adr) {
1665 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001666 EMIT(0xDB);
1667 emit_operand(edx, adr);
1668}
1669
1670
1671void Assembler::fistp_d(const Operand& adr) {
1672 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001673 EMIT(0xDF);
1674 emit_operand(edi, adr);
1675}
1676
1677
1678void Assembler::fabs() {
1679 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001680 EMIT(0xD9);
1681 EMIT(0xE1);
1682}
1683
1684
1685void Assembler::fchs() {
1686 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001687 EMIT(0xD9);
1688 EMIT(0xE0);
1689}
1690
1691
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001692void Assembler::fcos() {
1693 EnsureSpace ensure_space(this);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001694 EMIT(0xD9);
1695 EMIT(0xFF);
1696}
1697
1698
1699void Assembler::fsin() {
1700 EnsureSpace ensure_space(this);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001701 EMIT(0xD9);
1702 EMIT(0xFE);
1703}
1704
1705
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001706void Assembler::fptan() {
1707 EnsureSpace ensure_space(this);
1708 EMIT(0xD9);
1709 EMIT(0xF2);
1710}
1711
1712
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001713void Assembler::fyl2x() {
1714 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001715 EMIT(0xD9);
1716 EMIT(0xF1);
1717}
1718
1719
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001720void Assembler::f2xm1() {
1721 EnsureSpace ensure_space(this);
1722 EMIT(0xD9);
1723 EMIT(0xF0);
1724}
1725
1726
1727void Assembler::fscale() {
1728 EnsureSpace ensure_space(this);
1729 EMIT(0xD9);
1730 EMIT(0xFD);
1731}
1732
1733
1734void Assembler::fninit() {
1735 EnsureSpace ensure_space(this);
1736 EMIT(0xDB);
1737 EMIT(0xE3);
1738}
1739
1740
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001741void Assembler::fadd(int i) {
1742 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001743 emit_farith(0xDC, 0xC0, i);
1744}
1745
1746
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +00001747void Assembler::fadd_i(int i) {
1748 EnsureSpace ensure_space(this);
1749 emit_farith(0xD8, 0xC0, i);
1750}
1751
1752
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753void Assembler::fsub(int i) {
1754 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001755 emit_farith(0xDC, 0xE8, i);
1756}
1757
1758
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +00001759void Assembler::fsub_i(int i) {
1760 EnsureSpace ensure_space(this);
1761 emit_farith(0xD8, 0xE0, i);
1762}
1763
1764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001765void Assembler::fisub_s(const Operand& adr) {
1766 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001767 EMIT(0xDA);
1768 emit_operand(esp, adr);
1769}
1770
1771
danno@chromium.org169691d2013-07-15 08:01:13 +00001772void Assembler::fmul_i(int i) {
1773 EnsureSpace ensure_space(this);
1774 emit_farith(0xD8, 0xC8, i);
1775}
1776
1777
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778void Assembler::fmul(int i) {
1779 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001780 emit_farith(0xDC, 0xC8, i);
1781}
1782
1783
1784void Assembler::fdiv(int i) {
1785 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001786 emit_farith(0xDC, 0xF8, i);
1787}
1788
1789
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +00001790void Assembler::fdiv_i(int i) {
1791 EnsureSpace ensure_space(this);
1792 emit_farith(0xD8, 0xF0, i);
1793}
1794
1795
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001796void Assembler::faddp(int i) {
1797 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798 emit_farith(0xDE, 0xC0, i);
1799}
1800
1801
1802void Assembler::fsubp(int i) {
1803 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001804 emit_farith(0xDE, 0xE8, i);
1805}
1806
1807
1808void Assembler::fsubrp(int i) {
1809 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810 emit_farith(0xDE, 0xE0, i);
1811}
1812
1813
1814void Assembler::fmulp(int i) {
1815 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816 emit_farith(0xDE, 0xC8, i);
1817}
1818
1819
1820void Assembler::fdivp(int i) {
1821 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001822 emit_farith(0xDE, 0xF8, i);
1823}
1824
1825
1826void Assembler::fprem() {
1827 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001828 EMIT(0xD9);
1829 EMIT(0xF8);
1830}
1831
1832
1833void Assembler::fprem1() {
1834 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001835 EMIT(0xD9);
1836 EMIT(0xF5);
1837}
1838
1839
1840void Assembler::fxch(int i) {
1841 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001842 emit_farith(0xD9, 0xC8, i);
1843}
1844
1845
1846void Assembler::fincstp() {
1847 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001848 EMIT(0xD9);
1849 EMIT(0xF7);
1850}
1851
1852
1853void Assembler::ffree(int i) {
1854 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001855 emit_farith(0xDD, 0xC0, i);
1856}
1857
1858
1859void Assembler::ftst() {
1860 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001861 EMIT(0xD9);
1862 EMIT(0xE4);
1863}
1864
1865
1866void Assembler::fucomp(int i) {
1867 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001868 emit_farith(0xDD, 0xE8, i);
1869}
1870
1871
1872void Assembler::fucompp() {
1873 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874 EMIT(0xDA);
1875 EMIT(0xE9);
1876}
1877
1878
ager@chromium.org3811b432009-10-28 14:53:37 +00001879void Assembler::fucomi(int i) {
1880 EnsureSpace ensure_space(this);
ager@chromium.org3811b432009-10-28 14:53:37 +00001881 EMIT(0xDB);
1882 EMIT(0xE8 + i);
1883}
1884
1885
1886void Assembler::fucomip() {
1887 EnsureSpace ensure_space(this);
ager@chromium.org3811b432009-10-28 14:53:37 +00001888 EMIT(0xDF);
1889 EMIT(0xE9);
1890}
1891
1892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893void Assembler::fcompp() {
1894 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001895 EMIT(0xDE);
1896 EMIT(0xD9);
1897}
1898
1899
1900void Assembler::fnstsw_ax() {
1901 EnsureSpace ensure_space(this);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001902 EMIT(0xDF);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001903 EMIT(0xE0);
1904}
1905
1906
1907void Assembler::fwait() {
1908 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001909 EMIT(0x9B);
1910}
1911
1912
1913void Assembler::frndint() {
1914 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001915 EMIT(0xD9);
1916 EMIT(0xFC);
1917}
1918
1919
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001920void Assembler::fnclex() {
1921 EnsureSpace ensure_space(this);
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001922 EMIT(0xDB);
1923 EMIT(0xE2);
1924}
1925
1926
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001927void Assembler::sahf() {
1928 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001929 EMIT(0x9E);
1930}
1931
1932
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001933void Assembler::setcc(Condition cc, Register reg) {
1934 ASSERT(reg.is_byte_register());
1935 EnsureSpace ensure_space(this);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001936 EMIT(0x0F);
1937 EMIT(0x90 | cc);
1938 EMIT(0xC0 | reg.code());
1939}
1940
1941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942void Assembler::cvttss2si(Register dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001943 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001944 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001945 EMIT(0xF3);
1946 EMIT(0x0F);
1947 EMIT(0x2C);
1948 emit_operand(dst, src);
1949}
1950
1951
1952void Assembler::cvttsd2si(Register dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001953 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001954 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001955 EMIT(0xF2);
1956 EMIT(0x0F);
1957 EMIT(0x2C);
1958 emit_operand(dst, src);
1959}
1960
1961
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001962void Assembler::cvtsd2si(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001963 ASSERT(IsEnabled(SSE2));
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001964 EnsureSpace ensure_space(this);
1965 EMIT(0xF2);
1966 EMIT(0x0F);
1967 EMIT(0x2D);
1968 emit_sse_operand(dst, src);
1969}
1970
1971
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001972void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001973 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001974 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001975 EMIT(0xF2);
1976 EMIT(0x0F);
1977 EMIT(0x2A);
1978 emit_sse_operand(dst, src);
1979}
1980
1981
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001982void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001983 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001984 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001985 EMIT(0xF3);
1986 EMIT(0x0F);
1987 EMIT(0x5A);
1988 emit_sse_operand(dst, src);
1989}
1990
1991
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001992void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001993 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001994 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001995 EMIT(0xF2);
1996 EMIT(0x0F);
1997 EMIT(0x5A);
1998 emit_sse_operand(dst, src);
1999}
2000
2001
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002002void Assembler::addsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002003 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002004 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002005 EMIT(0xF2);
2006 EMIT(0x0F);
2007 EMIT(0x58);
2008 emit_sse_operand(dst, src);
2009}
2010
2011
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002012void Assembler::addsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002013 ASSERT(IsEnabled(SSE2));
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002014 EnsureSpace ensure_space(this);
2015 EMIT(0xF2);
2016 EMIT(0x0F);
2017 EMIT(0x58);
2018 emit_sse_operand(dst, src);
2019}
2020
2021
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002022void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002023 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002024 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002025 EMIT(0xF2);
2026 EMIT(0x0F);
2027 EMIT(0x59);
2028 emit_sse_operand(dst, src);
2029}
2030
2031
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002032void Assembler::mulsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002033 ASSERT(IsEnabled(SSE2));
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002034 EnsureSpace ensure_space(this);
2035 EMIT(0xF2);
2036 EMIT(0x0F);
2037 EMIT(0x59);
2038 emit_sse_operand(dst, src);
2039}
2040
2041
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002042void Assembler::subsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002043 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002044 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045 EMIT(0xF2);
2046 EMIT(0x0F);
2047 EMIT(0x5C);
2048 emit_sse_operand(dst, src);
2049}
2050
2051
2052void Assembler::divsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002053 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002054 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055 EMIT(0xF2);
2056 EMIT(0x0F);
2057 EMIT(0x5E);
2058 emit_sse_operand(dst, src);
2059}
2060
2061
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002062void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002063 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002064 EnsureSpace ensure_space(this);
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002065 EMIT(0x66);
2066 EMIT(0x0F);
2067 EMIT(0x57);
2068 emit_sse_operand(dst, src);
2069}
2070
2071
verwaest@chromium.org057bd502013-11-06 12:03:29 +00002072void Assembler::andps(XMMRegister dst, XMMRegister src) {
2073 EnsureSpace ensure_space(this);
2074 EMIT(0x0F);
2075 EMIT(0x54);
2076 emit_sse_operand(dst, src);
2077}
2078
2079
2080void Assembler::orps(XMMRegister dst, XMMRegister src) {
2081 EnsureSpace ensure_space(this);
2082 EMIT(0x0F);
2083 EMIT(0x56);
2084 emit_sse_operand(dst, src);
2085}
2086
2087
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002088void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2089 EnsureSpace ensure_space(this);
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002090 EMIT(0x0F);
2091 EMIT(0x57);
2092 emit_sse_operand(dst, src);
2093}
2094
2095
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002096void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +00002097 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002098 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002099 EMIT(0xF2);
2100 EMIT(0x0F);
2101 EMIT(0x51);
2102 emit_sse_operand(dst, src);
2103}
2104
2105
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002106void Assembler::andpd(XMMRegister dst, XMMRegister src) {
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +00002107 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002108 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002109 EMIT(0x66);
2110 EMIT(0x0F);
2111 EMIT(0x54);
2112 emit_sse_operand(dst, src);
2113}
2114
2115
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00002116void Assembler::orpd(XMMRegister dst, XMMRegister src) {
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +00002117 ASSERT(IsEnabled(SSE2));
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00002118 EnsureSpace ensure_space(this);
2119 EMIT(0x66);
2120 EMIT(0x0F);
2121 EMIT(0x56);
2122 emit_sse_operand(dst, src);
2123}
2124
2125
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002126void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002127 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002128 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002129 EMIT(0x66);
2130 EMIT(0x0F);
2131 EMIT(0x2E);
2132 emit_sse_operand(dst, src);
2133}
2134
2135
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002136void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002137 ASSERT(IsEnabled(SSE2));
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002138 EnsureSpace ensure_space(this);
2139 EMIT(0x66);
2140 EMIT(0x0F);
2141 EMIT(0x2E);
2142 emit_sse_operand(dst, src);
2143}
2144
2145
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002146void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002147 ASSERT(IsEnabled(SSE4_1));
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002148 EnsureSpace ensure_space(this);
2149 EMIT(0x66);
2150 EMIT(0x0F);
2151 EMIT(0x3A);
2152 EMIT(0x0B);
2153 emit_sse_operand(dst, src);
2154 // Mask precision exeption.
2155 EMIT(static_cast<byte>(mode) | 0x8);
2156}
2157
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00002158
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002159void Assembler::movmskpd(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002160 ASSERT(IsEnabled(SSE2));
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002161 EnsureSpace ensure_space(this);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002162 EMIT(0x66);
2163 EMIT(0x0F);
2164 EMIT(0x50);
2165 emit_sse_operand(dst, src);
2166}
2167
2168
ulan@chromium.org4121f232012-12-27 15:57:11 +00002169void Assembler::movmskps(Register dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002170 ASSERT(IsEnabled(SSE2));
ulan@chromium.org4121f232012-12-27 15:57:11 +00002171 EnsureSpace ensure_space(this);
2172 EMIT(0x0F);
2173 EMIT(0x50);
2174 emit_sse_operand(dst, src);
2175}
2176
2177
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002178void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002179 ASSERT(IsEnabled(SSE2));
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002180 EnsureSpace ensure_space(this);
2181 EMIT(0x66);
2182 EMIT(0x0F);
2183 EMIT(0x76);
2184 emit_sse_operand(dst, src);
2185}
2186
2187
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002188void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002189 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002190 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002191 EMIT(0xF2);
2192 EMIT(0x0F);
2193 EMIT(0xC2);
2194 emit_sse_operand(dst, src);
2195 EMIT(1); // LT == 1
2196}
2197
2198
2199void Assembler::movaps(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002200 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002201 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002202 EMIT(0x0F);
2203 EMIT(0x28);
2204 emit_sse_operand(dst, src);
2205}
2206
2207
2208void Assembler::movdqa(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002209 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002210 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002211 EMIT(0x66);
2212 EMIT(0x0F);
2213 EMIT(0x7F);
2214 emit_sse_operand(src, dst);
2215}
2216
2217
2218void Assembler::movdqa(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002219 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002220 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002221 EMIT(0x66);
2222 EMIT(0x0F);
2223 EMIT(0x6F);
2224 emit_sse_operand(dst, src);
2225}
2226
2227
2228void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002229 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002230 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002231 EMIT(0xF3);
2232 EMIT(0x0F);
2233 EMIT(0x7F);
2234 emit_sse_operand(src, dst);
2235}
2236
2237
2238void Assembler::movdqu(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002239 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002240 EnsureSpace ensure_space(this);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002241 EMIT(0xF3);
2242 EMIT(0x0F);
2243 EMIT(0x6F);
2244 emit_sse_operand(dst, src);
2245}
2246
2247
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002248void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002249 ASSERT(IsEnabled(SSE4_1));
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002250 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002251 EMIT(0x66);
2252 EMIT(0x0F);
2253 EMIT(0x38);
2254 EMIT(0x2A);
2255 emit_sse_operand(dst, src);
2256}
2257
2258
2259void Assembler::movntdq(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002260 ASSERT(IsEnabled(SSE2));
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002261 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002262 EMIT(0x66);
2263 EMIT(0x0F);
2264 EMIT(0xE7);
2265 emit_sse_operand(src, dst);
2266}
2267
2268
2269void Assembler::prefetch(const Operand& src, int level) {
2270 ASSERT(is_uint2(level));
2271 EnsureSpace ensure_space(this);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002272 EMIT(0x0F);
2273 EMIT(0x18);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002274 // Emit hint number in Reg position of RegR/M.
2275 XMMRegister code = XMMRegister::from_code(level);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002276 emit_sse_operand(code, src);
2277}
2278
2279
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002280void Assembler::movsd(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002281 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002282 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002283 EMIT(0xF2); // double
2284 EMIT(0x0F);
2285 EMIT(0x11); // store
2286 emit_sse_operand(src, dst);
2287}
2288
2289
2290void Assembler::movsd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002291 ASSERT(IsEnabled(SSE2));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292 EnsureSpace ensure_space(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002293 EMIT(0xF2); // double
2294 EMIT(0x0F);
2295 EMIT(0x10); // load
2296 emit_sse_operand(dst, src);
2297}
2298
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002299
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002300void Assembler::movsd(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002301 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002302 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002303 EMIT(0xF2);
2304 EMIT(0x0F);
2305 EMIT(0x10);
2306 emit_sse_operand(dst, src);
2307}
2308
2309
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002310void Assembler::movss(const Operand& dst, XMMRegister src ) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002311 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002312 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002313 EMIT(0xF3); // float
2314 EMIT(0x0F);
2315 EMIT(0x11); // store
2316 emit_sse_operand(src, dst);
2317}
2318
2319
2320void Assembler::movss(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002321 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002322 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002323 EMIT(0xF3); // float
2324 EMIT(0x0F);
2325 EMIT(0x10); // load
2326 emit_sse_operand(dst, src);
2327}
2328
2329
2330void Assembler::movss(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002331 ASSERT(IsEnabled(SSE2));
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002332 EnsureSpace ensure_space(this);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002333 EMIT(0xF3);
2334 EMIT(0x0F);
2335 EMIT(0x10);
2336 emit_sse_operand(dst, src);
2337}
2338
2339
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002340void Assembler::movd(XMMRegister dst, const Operand& src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002341 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002342 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002343 EMIT(0x66);
2344 EMIT(0x0F);
2345 EMIT(0x6E);
2346 emit_sse_operand(dst, src);
2347}
2348
2349
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002350void Assembler::movd(const Operand& dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002351 ASSERT(IsEnabled(SSE2));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002352 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002353 EMIT(0x66);
2354 EMIT(0x0F);
2355 EMIT(0x7E);
2356 emit_sse_operand(src, dst);
2357}
2358
2359
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002360void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
ulan@chromium.org837a67e2013-06-11 15:39:48 +00002361 ASSERT(IsEnabled(SSE4_1));
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002362 ASSERT(is_uint8(imm8));
2363 EnsureSpace ensure_space(this);
2364 EMIT(0x66);
2365 EMIT(0x0F);
2366 EMIT(0x3A);
2367 EMIT(0x17);
mstarzinger@chromium.orgb4968be2013-10-16 09:00:56 +00002368 emit_sse_operand(src, dst);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002369 EMIT(imm8);
2370}
2371
2372
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002373void Assembler::pand(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002374 ASSERT(IsEnabled(SSE2));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002375 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002376 EMIT(0x66);
2377 EMIT(0x0F);
2378 EMIT(0xDB);
2379 emit_sse_operand(dst, src);
2380}
2381
2382
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002383void Assembler::pxor(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002384 ASSERT(IsEnabled(SSE2));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002385 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002386 EMIT(0x66);
2387 EMIT(0x0F);
2388 EMIT(0xEF);
2389 emit_sse_operand(dst, src);
2390}
2391
2392
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002393void Assembler::por(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002394 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002395 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002396 EMIT(0x66);
2397 EMIT(0x0F);
2398 EMIT(0xEB);
2399 emit_sse_operand(dst, src);
2400}
2401
2402
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002403void Assembler::ptest(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002404 ASSERT(IsEnabled(SSE4_1));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002405 EnsureSpace ensure_space(this);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002406 EMIT(0x66);
2407 EMIT(0x0F);
2408 EMIT(0x38);
2409 EMIT(0x17);
2410 emit_sse_operand(dst, src);
2411}
2412
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002413
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002414void Assembler::psllq(XMMRegister reg, int8_t shift) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002415 ASSERT(IsEnabled(SSE2));
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002416 EnsureSpace ensure_space(this);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002417 EMIT(0x66);
2418 EMIT(0x0F);
2419 EMIT(0x73);
2420 emit_sse_operand(esi, reg); // esi == 6
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002421 EMIT(shift);
2422}
2423
2424
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002425void Assembler::psllq(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002426 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002427 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002428 EMIT(0x66);
2429 EMIT(0x0F);
2430 EMIT(0xF3);
2431 emit_sse_operand(dst, src);
2432}
2433
2434
2435void Assembler::psrlq(XMMRegister reg, int8_t shift) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002436 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002437 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002438 EMIT(0x66);
2439 EMIT(0x0F);
2440 EMIT(0x73);
2441 emit_sse_operand(edx, reg); // edx == 2
2442 EMIT(shift);
2443}
2444
2445
2446void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002447 ASSERT(IsEnabled(SSE2));
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002448 EnsureSpace ensure_space(this);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002449 EMIT(0x66);
2450 EMIT(0x0F);
2451 EMIT(0xD3);
2452 emit_sse_operand(dst, src);
2453}
2454
2455
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002456void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002457 ASSERT(IsEnabled(SSE2));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002458 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002459 EMIT(0x66);
2460 EMIT(0x0F);
2461 EMIT(0x70);
2462 emit_sse_operand(dst, src);
2463 EMIT(shuffle);
2464}
2465
2466
2467void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002468 ASSERT(IsEnabled(SSE4_1));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002469 EnsureSpace ensure_space(this);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002470 EMIT(0x66);
2471 EMIT(0x0F);
2472 EMIT(0x3A);
2473 EMIT(0x16);
2474 emit_sse_operand(src, dst);
2475 EMIT(offset);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +00002476}
2477
2478
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002479void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002480 ASSERT(IsEnabled(SSE4_1));
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002481 EnsureSpace ensure_space(this);
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002482 EMIT(0x66);
2483 EMIT(0x0F);
2484 EMIT(0x3A);
2485 EMIT(0x22);
2486 emit_sse_operand(dst, src);
2487 EMIT(offset);
2488}
2489
2490
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002491void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2492 Register ireg = { reg.code() };
2493 emit_operand(ireg, adr);
2494}
2495
2496
2497void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2498 EMIT(0xC0 | dst.code() << 3 | src.code());
2499}
2500
2501
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002502void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2503 EMIT(0xC0 | dst.code() << 3 | src.code());
2504}
2505
2506
mstarzinger@chromium.orgb4968be2013-10-16 09:00:56 +00002507void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2508 EMIT(0xC0 | (dst.code() << 3) | src.code());
2509}
2510
2511
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002512void Assembler::Print() {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002513 Disassembler::Decode(isolate(), stdout, buffer_, pc_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002514}
2515
2516
2517void Assembler::RecordJSReturn() {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002518 positions_recorder()->WriteRecordedPositions();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002519 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00002520 RecordRelocInfo(RelocInfo::JS_RETURN);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002521}
2522
2523
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002524void Assembler::RecordDebugBreakSlot() {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002525 positions_recorder()->WriteRecordedPositions();
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002526 EnsureSpace ensure_space(this);
2527 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2528}
2529
2530
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002531void Assembler::RecordComment(const char* msg, bool force) {
2532 if (FLAG_code_comments || force) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002533 EnsureSpace ensure_space(this);
ager@chromium.org236ad962008-09-25 09:45:57 +00002534 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002535 }
2536}
2537
2538
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002539void Assembler::GrowBuffer() {
ager@chromium.org5c838252010-02-19 08:53:10 +00002540 ASSERT(overflow());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002541 if (!own_buffer_) FATAL("external code buffer is too small");
2542
ager@chromium.org5c838252010-02-19 08:53:10 +00002543 // Compute new buffer size.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002544 CodeDesc desc; // the new buffer
2545 if (buffer_size_ < 4*KB) {
2546 desc.buffer_size = 4*KB;
2547 } else {
2548 desc.buffer_size = 2*buffer_size_;
2549 }
2550 // Some internal data structures overflow for very large buffers,
2551 // they must ensure that kMaximalBufferSize is not too large.
2552 if ((desc.buffer_size > kMaximalBufferSize) ||
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002553 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002554 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2555 }
2556
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002557 // Set up new buffer.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002558 desc.buffer = NewArray<byte>(desc.buffer_size);
2559 desc.instr_size = pc_offset();
2560 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2561
2562 // Clear the buffer in debug mode. Use 'int3' instructions to make
2563 // sure to get into problems if we ever run uninitialized code.
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002564#ifdef DEBUG
2565 memset(desc.buffer, 0xCC, desc.buffer_size);
2566#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002567
ager@chromium.org5c838252010-02-19 08:53:10 +00002568 // Copy the data.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002569 int pc_delta = desc.buffer - buffer_;
2570 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002571 OS::MemMove(desc.buffer, buffer_, desc.instr_size);
2572 OS::MemMove(rc_delta + reloc_info_writer.pos(),
2573 reloc_info_writer.pos(), desc.reloc_size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002574
ager@chromium.org5c838252010-02-19 08:53:10 +00002575 // Switch buffers.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002576 if (isolate()->assembler_spare_buffer() == NULL &&
2577 buffer_size_ == kMinimalBufferSize) {
2578 isolate()->set_assembler_spare_buffer(buffer_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002579 } else {
2580 DeleteArray(buffer_);
2581 }
2582 buffer_ = desc.buffer;
2583 buffer_size_ = desc.buffer_size;
2584 pc_ += pc_delta;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2586 reloc_info_writer.last_pc() + pc_delta);
2587
ager@chromium.org5c838252010-02-19 08:53:10 +00002588 // Relocate runtime entries.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002589 for (RelocIterator it(desc); !it.done(); it.next()) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002590 RelocInfo::Mode rmode = it.rinfo()->rmode();
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00002591 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002592 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2593 if (*p != 0) { // 0 means uninitialized.
2594 *p += pc_delta;
2595 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002596 }
2597 }
2598
2599 ASSERT(!overflow());
2600}
2601
2602
2603void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
2604 ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode
2605 ASSERT(is_uint8(imm8));
2606 ASSERT((op1 & 0x01) == 0); // should be 8bit operation
2607 EMIT(op1);
2608 EMIT(op2 | dst.code());
2609 EMIT(imm8);
2610}
2611
2612
2613void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
2614 ASSERT((0 <= sel) && (sel <= 7));
2615 Register ireg = { sel };
2616 if (x.is_int8()) {
2617 EMIT(0x83); // using a sign-extended 8-bit immediate.
2618 emit_operand(ireg, dst);
2619 EMIT(x.x_ & 0xFF);
2620 } else if (dst.is_reg(eax)) {
2621 EMIT((sel << 3) | 0x05); // short form if the destination is eax.
2622 emit(x);
2623 } else {
2624 EMIT(0x81); // using a literal 32-bit immediate.
2625 emit_operand(ireg, dst);
2626 emit(x);
2627 }
2628}
2629
2630
2631void Assembler::emit_operand(Register reg, const Operand& adr) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002632 const unsigned length = adr.len_;
2633 ASSERT(length > 0);
2634
2635 // Emit updated ModRM byte containing the given register.
2636 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2637
2638 // Emit the rest of the encoded operand.
2639 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2640 pc_ += length;
2641
2642 // Emit relocation information if necessary.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002643 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002644 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32
2645 RecordRelocInfo(adr.rmode_);
2646 pc_ += sizeof(int32_t);
2647 }
2648}
2649
2650
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002651void Assembler::emit_farith(int b1, int b2, int i) {
2652 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2653 ASSERT(0 <= i && i < 8); // illegal stack offset
2654 EMIT(b1);
2655 EMIT(b2 + i);
2656}
2657
2658
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002659void Assembler::db(uint8_t data) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002660 EnsureSpace ensure_space(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002661 EMIT(data);
2662}
2663
2664
2665void Assembler::dd(uint32_t data) {
2666 EnsureSpace ensure_space(this);
2667 emit(data);
ager@chromium.org236ad962008-09-25 09:45:57 +00002668}
2669
2670
2671void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002672 ASSERT(!RelocInfo::IsNone(rmode));
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00002673 // Don't record external references unless the heap will be serialized.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002674 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2675#ifdef DEBUG
2676 if (!Serializer::enabled()) {
2677 Serializer::TooLateToEnableNow();
2678 }
2679#endif
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +00002680 if (!Serializer::enabled() && !emit_debug_code()) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002681 return;
2682 }
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00002683 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002684 RelocInfo rinfo(pc_, rmode, data, NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002685 reloc_info_writer.Write(&rinfo);
2686}
2687
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002688
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002689#ifdef GENERATED_CODE_COVERAGE
2690static FILE* coverage_log = NULL;
2691
2692
2693static void InitCoverageLog() {
2694 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
2695 if (file_name != NULL) {
2696 coverage_log = fopen(file_name, "aw+");
2697 }
2698}
2699
2700
2701void LogGeneratedCodeCoverage(const char* file_line) {
2702 const char* return_address = (&file_line)[-1];
2703 char* push_insn = const_cast<char*>(return_address - 12);
2704 push_insn[0] = 0xeb; // Relative branch insn.
2705 push_insn[1] = 13; // Skip over coverage insns.
2706 if (coverage_log != NULL) {
2707 fprintf(coverage_log, "%s\n", file_line);
2708 fflush(coverage_log);
2709 }
2710}
2711
2712#endif
2713
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002714} } // namespace v8::internal
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002715
2716#endif // V8_TARGET_ARCH_IA32