assembler_x86_64.cc revision 8ae3ffb29489a127f2a6242c33845dac8d50e508
1fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko/*
2fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Copyright (C) 2014 The Android Open Source Project
3fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko *
4fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Licensed under the Apache License, Version 2.0 (the "License");
5fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * you may not use this file except in compliance with the License.
6fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * You may obtain a copy of the License at
7fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko *
8fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko *      http://www.apache.org/licenses/LICENSE-2.0
9fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko *
10fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Unless required by applicable law or agreed to in writing, software
11fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * distributed under the License is distributed on an "AS IS" BASIS,
12fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * See the License for the specific language governing permissions and
14fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * limitations under the License.
15fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko */
16fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
17fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "assembler_x86_64.h"
18fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
19fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "base/casts.h"
20fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "entrypoints/quick/quick_entrypoints.h"
21fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "memory_region.h"
22fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "thread.h"
23fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
24fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkonamespace art {
25fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkonamespace x86_64 {
26fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
27dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersstd::ostream& operator<<(std::ostream& os, const CpuRegister& reg) {
28dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  return os << reg.AsRegister();
29dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
30dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
31fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkostd::ostream& operator<<(std::ostream& os, const XmmRegister& reg) {
32dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  return os << reg.AsFloatRegister();
33fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
34fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
35fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkostd::ostream& operator<<(std::ostream& os, const X87Register& reg) {
36fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return os << "ST" << static_cast<int>(reg);
37fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
38fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
39dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::call(CpuRegister reg) {
40fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
41dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
42fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
43dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(2, reg.LowBits());
44fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
45fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
46fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
47fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::call(const Address& address) {
48fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
49dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
50fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
51fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(2, address);
52fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
53fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
54fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
55fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::call(Label* label) {
56fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
57fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xE8);
58fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  static const int kSize = 5;
591cf95287364948689f6a1a320567acd7728e94a3Nicolas Geoffray  // Offset by one because we already have emitted the opcode.
601cf95287364948689f6a1a320567acd7728e94a3Nicolas Geoffray  EmitLabel(label, kSize - 1);
61fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
62fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
63dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::pushq(CpuRegister reg) {
64fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
65dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
66dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0x50 + reg.LowBits());
67fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
68fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
69fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
70fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::pushq(const Address& address) {
71fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
72dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
73fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
74fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(6, address);
75fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
76fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
77fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
78fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::pushq(const Immediate& imm) {
79fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
805a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // pushq only supports 32b immediate.
81fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (imm.is_int8()) {
82fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x6A);
83fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(imm.value() & 0xFF);
84fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
85fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x68);
86fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(imm);
87fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
88fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
89fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
90fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
91dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::popq(CpuRegister reg) {
92fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
93dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
94dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0x58 + reg.LowBits());
95fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
96fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
97fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
98fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::popq(const Address& address) {
99fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
100dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
101fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x8F);
102fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, address);
103fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
104fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
105fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
106dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movq(CpuRegister dst, const Immediate& imm) {
107fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1085a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (imm.is_int32()) {
1095a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    // 32 bit. Note: sign-extends.
1105a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitRex64(dst);
1115a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitUint8(0xC7);
1125a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitRegisterOperand(0, dst.LowBits());
1135a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt32(static_cast<int32_t>(imm.value()));
1145a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  } else {
1155a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitRex64(dst);
1165a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitUint8(0xB8 + dst.LowBits());
1175a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt64(imm.value());
1185a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
119fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
120fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
121fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
122dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movl(CpuRegister dst, const Immediate& imm) {
123946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain  CHECK(imm.is_int32());
124fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
125dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
126dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xB8 + dst.LowBits());
127fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitImmediate(imm);
128fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
129fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
130fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
13140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::movq(const Address& dst, const Immediate& imm) {
13240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  CHECK(imm.is_int32());
13340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(dst);
13540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xC7);
13640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(0, dst);
13740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitImmediate(imm);
13840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
13940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
14040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
141dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movq(CpuRegister dst, CpuRegister src) {
142fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1435a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // 0x89 is movq r/m64 <- r64, with op1 in r/m and op2 in reg: so reverse EmitRex64
1445a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(src, dst);
145fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
146dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(src.LowBits(), dst.LowBits());
147fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
148fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
149fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
150dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movl(CpuRegister dst, CpuRegister src) {
151fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
152dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
153ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  EmitUint8(0x8B);
154ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  EmitRegisterOperand(dst.LowBits(), src.LowBits());
155fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
156fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
157fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
158dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movq(CpuRegister dst, const Address& src) {
159fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
160dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(dst, src);
161fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x8B);
162dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
163fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
164fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
165fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
166dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movl(CpuRegister dst, const Address& src) {
167fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
168dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
169fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x8B);
170dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
171fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
172fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
173fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
174dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movq(const Address& dst, CpuRegister src) {
175fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
176dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(src, dst);
177fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
178dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
179fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
180fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
181fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
182dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movl(const Address& dst, CpuRegister src) {
183fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
184dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(src, dst);
185fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
186dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
187fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
188fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
189fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movl(const Address& dst, const Immediate& imm) {
190fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
191dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
192fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC7);
193fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, dst);
194fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitImmediate(imm);
195fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
196fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1977a08fb53bd13c74dec92256bef22a37250db1373Mark Mendellvoid X86_64Assembler::movntl(const Address& dst, CpuRegister src) {
1987a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1997a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  EmitOptionalRex32(src, dst);
2007a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  EmitUint8(0x0F);
2017a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  EmitUint8(0xC3);
2027a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  EmitOperand(src.LowBits(), dst);
2037a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell}
2047a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell
2057a08fb53bd13c74dec92256bef22a37250db1373Mark Mendellvoid X86_64Assembler::movntq(const Address& dst, CpuRegister src) {
2067a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2077a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  EmitRex64(src, dst);
2087a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  EmitUint8(0x0F);
2097a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  EmitUint8(0xC3);
2107a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell  EmitOperand(src.LowBits(), dst);
2117a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell}
21271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
21371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::cmov(Condition c, CpuRegister dst, CpuRegister src) {
21471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  cmov(c, dst, src, true);
21571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
21671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
21771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::cmov(Condition c, CpuRegister dst, CpuRegister src, bool is64bit) {
21871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
21971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, is64bit, dst.NeedsRex(), false, src.NeedsRex());
22071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
22171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x40 + c);
22271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitRegisterOperand(dst.LowBits(), src.LowBits());
22371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
22471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
22571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
226dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxb(CpuRegister dst, CpuRegister src) {
227fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
228dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(dst, src);
229fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
230fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB6);
231dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
232fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
233fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
234fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
235dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxb(CpuRegister dst, const Address& src) {
236fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
237d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // Byte register is only in the source register form, so we don't use
238d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // EmitOptionalByteRegNormalizingRex32(dst, src);
239d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex32(dst, src);
240fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
241fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB6);
242dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
243fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
244fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
245fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
246dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxb(CpuRegister dst, CpuRegister src) {
247fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
248dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(dst, src);
249fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
250fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBE);
251dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
252fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
253fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
254fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
255dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxb(CpuRegister dst, const Address& src) {
256fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
257d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // Byte register is only in the source register form, so we don't use
258d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // EmitOptionalByteRegNormalizingRex32(dst, src);
259d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex32(dst, src);
260fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
261fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBE);
262dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
263fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
264fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
265fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
266dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movb(CpuRegister /*dst*/, const Address& /*src*/) {
267fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  LOG(FATAL) << "Use movzxb or movsxb instead.";
268fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
269fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
270fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
271dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movb(const Address& dst, CpuRegister src) {
272fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
273dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(src, dst);
274fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x88);
275dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
276fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
277fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
278fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
279fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movb(const Address& dst, const Immediate& imm) {
280fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
28126a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOptionalRex32(dst);
282fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC6);
283dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(Register::RAX, dst);
284fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_int8());
285fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
286fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
287fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
288fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
289dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxw(CpuRegister dst, CpuRegister src) {
290fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
291dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
292fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
293fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB7);
294dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
295fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
296fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
297fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
298dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxw(CpuRegister dst, const Address& src) {
299fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
300dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
301fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
302fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB7);
303dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
304fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
305fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
306fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
307dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxw(CpuRegister dst, CpuRegister src) {
308fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
309dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
310fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
311fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBF);
312dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
313fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
314fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
315fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
316dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxw(CpuRegister dst, const Address& src) {
317fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
318dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
319fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
320fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBF);
321dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
322fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
323fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
324fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
325dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movw(CpuRegister /*dst*/, const Address& /*src*/) {
326fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  LOG(FATAL) << "Use movzxw or movsxw instead.";
327fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
328fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
329fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
330dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movw(const Address& dst, CpuRegister src) {
331fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
332fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperandSizeOverride();
333e4ded41ae2648973d5fed8c6bafaebf917ea7d17Nicolas Geoffray  EmitOptionalRex32(src, dst);
334fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
335dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
336fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
337fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
338fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
33926a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffrayvoid X86_64Assembler::movw(const Address& dst, const Immediate& imm) {
34026a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
34126a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOperandSizeOverride();
34226a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOptionalRex32(dst);
34326a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(0xC7);
34426a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOperand(Register::RAX, dst);
345b6e7206ad7a426adda9cfd649a4ef969607d79d6Nicolas Geoffray  CHECK(imm.is_uint16() || imm.is_int16());
34626a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(imm.value() & 0xFF);
34726a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(imm.value() >> 8);
34826a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray}
34926a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray
35026a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray
351dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::leaq(CpuRegister dst, const Address& src) {
352fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
353dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(dst, src);
354fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x8D);
355dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
356fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
357fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
358fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
359748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffrayvoid X86_64Assembler::leal(CpuRegister dst, const Address& src) {
360748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
361748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitOptionalRex32(dst, src);
362748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitUint8(0x8D);
363748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitOperand(dst.LowBits(), src);
364748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray}
365748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray
366748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray
3677fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffrayvoid X86_64Assembler::movaps(XmmRegister dst, XmmRegister src) {
3687fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3697fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitOptionalRex32(dst, src);
3707fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitUint8(0x0F);
3717fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitUint8(0x28);
372102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  EmitXmmRegisterOperand(dst.LowBits(), src);
3737fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray}
3747fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray
3757fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray
376fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(XmmRegister dst, const Address& src) {
377fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
378fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
379dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
380fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
381fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x10);
382dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
383fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
384fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
385fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
386fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(const Address& dst, XmmRegister src) {
387fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
389dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(src, dst);
390fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
391fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
392dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
393fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
394fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
395fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
396fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(XmmRegister dst, XmmRegister src) {
397fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
398fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
399851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);  // Movss is MR encoding instead of the usual RM.
400fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
401fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
402dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(src.LowBits(), dst);
403fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
404fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
405fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
406dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillainvoid X86_64Assembler::movsxd(CpuRegister dst, CpuRegister src) {
407dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
40857a88d4ac205874dc85d22f9f6a9ca3c4c373eebNicolas Geoffray  EmitRex64(dst, src);
409dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitUint8(0x63);
410dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitRegisterOperand(dst.LowBits(), src.LowBits());
411dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain}
412dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
413dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
414dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillainvoid X86_64Assembler::movsxd(CpuRegister dst, const Address& src) {
415dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
4167fd8b59ab9fcd896a95883ce7be781d74e849d60Mark Mendell  EmitRex64(dst, src);
417dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitUint8(0x63);
418dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitOperand(dst.LowBits(), src);
419dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain}
420dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
421dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
422dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movd(XmmRegister dst, CpuRegister src) {
42371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  movd(dst, src, true);
42471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
42571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
42671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(CpuRegister dst, XmmRegister src) {
42771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  movd(dst, src, true);
42871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
42971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
43071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(XmmRegister dst, CpuRegister src, bool is64bit) {
431fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
43371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, is64bit, dst.NeedsRex(), false, src.NeedsRex());
434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x6E);
436dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
437fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
438fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
43971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(CpuRegister dst, XmmRegister src, bool is64bit) {
440fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
441fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
44271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, is64bit, src.NeedsRex(), false, dst.NeedsRex());
443fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
444fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x7E);
445dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), Operand(dst));
446fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
447fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
448fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
449fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addss(XmmRegister dst, XmmRegister src) {
450fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
451fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
452dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
453fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
455dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
456fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
457fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
458fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
459fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addss(XmmRegister dst, const Address& src) {
460fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
461fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
462dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
463fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
464fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
465dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
467fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
468fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
469fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subss(XmmRegister dst, XmmRegister src) {
470fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
471fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
472dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
473fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
475dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
476fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
477fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
478fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
479fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subss(XmmRegister dst, const Address& src) {
480fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
482dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
483fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
484fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
485dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
486fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
487fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
488fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
489fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulss(XmmRegister dst, XmmRegister src) {
490fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
491fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
492dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
493fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
494fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
495dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
496fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
497fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
498fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
499fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulss(XmmRegister dst, const Address& src) {
500fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
501fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
502dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
503fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
504fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
505dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
506fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
507fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
508fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
509fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divss(XmmRegister dst, XmmRegister src) {
510fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
511fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
512dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
513fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
514fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
515dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
516fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
517fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
518fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
519fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divss(XmmRegister dst, const Address& src) {
520fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
521fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
522dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
523fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
524fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
525dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
527fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
528fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
529fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::flds(const Address& src) {
530fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
531fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
532fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, src);
533fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
534fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
535fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
53624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fsts(const Address& dst) {
53724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
53824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xD9);
53924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitOperand(2, dst);
54024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
54124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
54224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
543fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fstps(const Address& dst) {
544fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
545fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
546fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
547fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
548fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
549fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
550fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(XmmRegister dst, const Address& src) {
551fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
552fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
553dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
554fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
555fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x10);
556dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
557fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
558fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
559fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
560fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(const Address& dst, XmmRegister src) {
561fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
562fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
563dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(src, dst);
564fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
565fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
566dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
567fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
568fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
569fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
570fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(XmmRegister dst, XmmRegister src) {
571fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
572fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
573851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);  // Movsd is MR encoding instead of the usual RM.
574fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
576dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(src.LowBits(), dst);
577fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
578fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
579fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
580fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addsd(XmmRegister dst, XmmRegister src) {
581fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
582fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
583dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
584fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
585fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
586dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
587fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
588fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
589fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
590fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addsd(XmmRegister dst, const Address& src) {
591fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
592fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
593dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
594fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
595fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
596dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
597fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
598fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
599fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
600fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subsd(XmmRegister dst, XmmRegister src) {
601fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
602fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
603dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
604fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
605fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
606dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
607fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
608fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
609fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
610fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subsd(XmmRegister dst, const Address& src) {
611fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
612fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
613dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
614fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
615fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
616dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
617fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
618fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
619fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
620fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulsd(XmmRegister dst, XmmRegister src) {
621fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
622fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
623dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
624fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
626dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
627fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
628fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
629fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
630fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulsd(XmmRegister dst, const Address& src) {
631fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
632fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
633dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
634fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
635fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
636dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
637fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
638fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
639fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
640fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divsd(XmmRegister dst, XmmRegister src) {
641fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
642fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
643dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
644fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
645fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
646dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
647fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
648fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
649fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divsd(XmmRegister dst, const Address& src) {
651fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
653dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
654fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
655fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
656dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
657fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
658fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
659fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
660dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src) {
6616d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  cvtsi2ss(dst, src, false);
6626d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain}
6636d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain
6646d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain
6656d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillainvoid X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src, bool is64bit) {
666fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
667fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
6686d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  if (is64bit) {
6696d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
6706d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    EmitRex64(dst, src);
6716d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  } else {
6726d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    EmitOptionalRex32(dst, src);
6736d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  }
674fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
675fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2A);
676dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
677fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
678fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
679fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
68040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::cvtsi2ss(XmmRegister dst, const Address& src, bool is64bit) {
68140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
68240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xF3);
68340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  if (is64bit) {
68440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    // Emit a REX.W prefix if the operand size is 64 bits.
68540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    EmitRex64(dst, src);
68640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  } else {
68740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    EmitOptionalRex32(dst, src);
68840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  }
68940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
69040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2A);
69140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
69240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
69340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
69440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
695dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsi2sd(XmmRegister dst, CpuRegister src) {
696647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  cvtsi2sd(dst, src, false);
697647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain}
698647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain
699647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain
700647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillainvoid X86_64Assembler::cvtsi2sd(XmmRegister dst, CpuRegister src, bool is64bit) {
701fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
702fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
703647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  if (is64bit) {
704647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
705647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    EmitRex64(dst, src);
706647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  } else {
707647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    EmitOptionalRex32(dst, src);
708647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  }
709fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
710fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2A);
711dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
712fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
713fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
714fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
71540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::cvtsi2sd(XmmRegister dst, const Address& src, bool is64bit) {
71640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
71740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xF2);
71840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  if (is64bit) {
71940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    // Emit a REX.W prefix if the operand size is 64 bits.
72040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    EmitRex64(dst, src);
72140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  } else {
72240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    EmitOptionalRex32(dst, src);
72340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  }
72440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
72540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2A);
72640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
72740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
72840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
72940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
730dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtss2si(CpuRegister dst, XmmRegister src) {
731fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
732fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
733dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
734fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
735fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2D);
736dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
737fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
738fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
739fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
740fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) {
741fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
742fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
743dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
744fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
745fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5A);
746dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
747fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
748fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
749fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
75040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::cvtss2sd(XmmRegister dst, const Address& src) {
75140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
75240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xF3);
75340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(dst, src);
75440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
75540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x5A);
75640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
75740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
75840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
75940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
760dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsd2si(CpuRegister dst, XmmRegister src) {
761fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
762fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
763dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
764fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
765fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2D);
766dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
767fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
768fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
769fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
770dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvttss2si(CpuRegister dst, XmmRegister src) {
771624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  cvttss2si(dst, src, false);
772624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain}
773624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
774624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
775624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainvoid X86_64Assembler::cvttss2si(CpuRegister dst, XmmRegister src, bool is64bit) {
776fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
777fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
778624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  if (is64bit) {
779624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
780624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    EmitRex64(dst, src);
781624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  } else {
782624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    EmitOptionalRex32(dst, src);
783624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  }
784fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
785fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2C);
786dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
787fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
788fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
789fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
790dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvttsd2si(CpuRegister dst, XmmRegister src) {
7914c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  cvttsd2si(dst, src, false);
7924c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain}
7934c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain
7944c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain
7954c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillainvoid X86_64Assembler::cvttsd2si(CpuRegister dst, XmmRegister src, bool is64bit) {
796fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
797fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
7984c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  if (is64bit) {
7994c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
8004c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    EmitRex64(dst, src);
8014c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  } else {
8024c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    EmitOptionalRex32(dst, src);
8034c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  }
804fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
805fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2C);
806dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
807fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
808fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
809fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
810fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) {
811fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
812fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
813dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
814fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
815fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5A);
816dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
817fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
818fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
819fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
82040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::cvtsd2ss(XmmRegister dst, const Address& src) {
82140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
82240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xF2);
82340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(dst, src);
82440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
82540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x5A);
82640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
82740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
82840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
82940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
830fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) {
831fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
832fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
833dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
834fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
835fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xE6);
836dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
837fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
838fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
839fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
840fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::comiss(XmmRegister a, XmmRegister b) {
841fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
842dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(a, b);
843fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
844fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2F);
845dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(a.LowBits(), b);
846fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
84940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::comiss(XmmRegister a, const Address& b) {
85040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
85140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(a, b);
85240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
85340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2F);
85440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(a.LowBits(), b);
85540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
85640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
85740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
858fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::comisd(XmmRegister a, XmmRegister b) {
859fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
860fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
861dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(a, b);
862fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
863fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2F);
864dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(a.LowBits(), b);
865fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
866fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
86740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
86840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::comisd(XmmRegister a, const Address& b) {
86940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
87040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x66);
87140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(a, b);
87240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
87340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2F);
87440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(a.LowBits(), b);
87540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
87640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
87740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
878ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravlevoid X86_64Assembler::ucomiss(XmmRegister a, XmmRegister b) {
879ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
880ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitOptionalRex32(a, b);
881ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x0F);
882ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x2E);
883ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitXmmRegisterOperand(a.LowBits(), b);
884ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle}
885ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
886ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
88740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::ucomiss(XmmRegister a, const Address& b) {
88840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
88940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(a, b);
89040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
89140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2E);
89240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(a.LowBits(), b);
89340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
89440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
89540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
896ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravlevoid X86_64Assembler::ucomisd(XmmRegister a, XmmRegister b) {
897ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
898ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x66);
899ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitOptionalRex32(a, b);
900ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x0F);
901ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x2E);
902ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitXmmRegisterOperand(a.LowBits(), b);
903ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle}
904ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
905fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
90640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::ucomisd(XmmRegister a, const Address& b) {
90740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
90840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x66);
90940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(a, b);
91040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
91140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2E);
91240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(a.LowBits(), b);
91340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
91440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
91540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
916fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendellvoid X86_64Assembler::roundsd(XmmRegister dst, XmmRegister src, const Immediate& imm) {
917fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
918fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x66);
919fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitOptionalRex32(dst, src);
920fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0F);
921fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x3A);
922fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0B);
923fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitXmmRegisterOperand(dst.LowBits(), src);
924fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(imm.value());
925fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell}
926fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
927fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
928fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendellvoid X86_64Assembler::roundss(XmmRegister dst, XmmRegister src, const Immediate& imm) {
929fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
930fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x66);
931fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitOptionalRex32(dst, src);
932fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0F);
933fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x3A);
934fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0A);
935fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitXmmRegisterOperand(dst.LowBits(), src);
936fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(imm.value());
937fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell}
938fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
939fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
940fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
941fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
942fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
943dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
944fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
945fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x51);
946dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
947fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
948fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
949fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
950fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::sqrtss(XmmRegister dst, XmmRegister src) {
951fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
952fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
953dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
954fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
955fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x51);
956dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
957fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
958fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
959fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
960fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorpd(XmmRegister dst, const Address& src) {
961fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
962fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
963dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
966dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
967fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
968fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
969fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
970fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorpd(XmmRegister dst, XmmRegister src) {
971fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
972fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
973dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
974fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
975fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
976dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
977fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
978fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
979fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
980fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorps(XmmRegister dst, const Address& src) {
981fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
982dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
983fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
984fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
985dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
986fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
987fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
988fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
989fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorps(XmmRegister dst, XmmRegister src) {
990fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
991dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
992fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
993fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
994dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
995fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
996fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
997fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
998fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::andpd(XmmRegister dst, const Address& src) {
999fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1000fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
1001dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1002fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x54);
1004dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
1005fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1006fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
100771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::andpd(XmmRegister dst, XmmRegister src) {
100871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
100971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x66);
101071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
101171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
101271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x54);
101371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
101471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
101571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
101671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::andps(XmmRegister dst, XmmRegister src) {
101771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
101871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
101971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
102071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x54);
102171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
102271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
102371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
102471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::orpd(XmmRegister dst, XmmRegister src) {
102571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
102671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x66);
102771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
102871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
102971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x56);
103071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
103171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
103271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
103371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::orps(XmmRegister dst, XmmRegister src) {
103471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
103571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
103671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
103771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x56);
103871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
103971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
1040fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1041fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fldl(const Address& src) {
1042fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1043fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
1044fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, src);
1045fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1046fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1047fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
104824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fstl(const Address& dst) {
104924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
105024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDD);
105124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitOperand(2, dst);
105224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
105324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
105424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
1055fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fstpl(const Address& dst) {
1056fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1057fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
1058fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
1059fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1060fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1061fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
106224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fstsw() {
106324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
106424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0x9B);
106524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDF);
106624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xE0);
106724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
106824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
106924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
1070fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fnstcw(const Address& dst) {
1071fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1072fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1073fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(7, dst);
1074fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1075fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1076fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1077fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fldcw(const Address& src) {
1078fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1079fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1080fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, src);
1081fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1082fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1083fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1084fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fistpl(const Address& dst) {
1085fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1086fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDF);
1087fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(7, dst);
1088fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1089fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1090fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1091fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fistps(const Address& dst) {
1092fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1093fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDB);
1094fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
1095fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1096fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1097fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1098fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fildl(const Address& src) {
1099fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1100fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDF);
1101fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, src);
1102fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1103fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1104fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
11050a18601f141d864a26d4b74ff5613e69ae411483Roland Levillainvoid X86_64Assembler::filds(const Address& src) {
11060a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
11070a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  EmitUint8(0xDB);
11080a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  EmitOperand(0, src);
11090a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain}
11100a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain
11110a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain
1112fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fincstp() {
1113fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1114fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1115fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1116fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1117fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1118fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1119fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ffree(const Immediate& index) {
1120fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(index.value(), 7);
1121fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1122fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
1123fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC0 + index.value());
1124fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1125fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1126fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1127fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fsin() {
1128fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1129fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1130fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFE);
1131fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1132fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1133fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1134fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fcos() {
1135fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1136fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1137fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1138fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1139fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1140fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1141fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fptan() {
1142fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1143fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1144fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
1145fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1146fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
114724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fucompp() {
114824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
114924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDA);
115024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xE9);
115124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
115224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
115324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
115424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fprem() {
115524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
115624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xD9);
115724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xF8);
115824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
115924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
1160fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1161dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xchgl(CpuRegister dst, CpuRegister src) {
1162fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1163851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // There is a short version for rax.
1164851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't
1165851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // work.
1166851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool src_rax = src.AsRegister() == RAX;
1167851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool dst_rax = dst.AsRegister() == RAX;
1168851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  if (src_rax || dst_rax) {
1169851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOptionalRex32(src_rax ? dst : src);
1170851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits()));
1171851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    return;
1172851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1173851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1174851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // General case.
1175851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);
1176fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x87);
1177851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
1178fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1179fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1180ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1181ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffrayvoid X86_64Assembler::xchgq(CpuRegister dst, CpuRegister src) {
1182ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1183851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // There is a short version for rax.
1184851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't
1185851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // work.
1186851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool src_rax = src.AsRegister() == RAX;
1187851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool dst_rax = dst.AsRegister() == RAX;
1188851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  if (src_rax || dst_rax) {
1189851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // If src == target, emit a nop instead.
1190851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    if (src_rax && dst_rax) {
1191851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitUint8(0x90);
1192851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    } else {
1193851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitRex64(src_rax ? dst : src);
1194851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits()));
1195851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    }
1196851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    return;
1197851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1198851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1199851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // General case.
1200851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRex64(src, dst);
1201ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  EmitUint8(0x87);
1202851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
1203ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray}
1204ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1205ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1206dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xchgl(CpuRegister reg, const Address& address) {
1207fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1208dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1209fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x87);
1210dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1211fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1212fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1213fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
12143c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffrayvoid X86_64Assembler::cmpw(const Address& address, const Immediate& imm) {
12153c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12163c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitOptionalRex32(address);
12173c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitUint8(0x66);
12183c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitComplex(7, address, imm);
12193c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray}
12203c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
12213c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
1222dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg, const Immediate& imm) {
1223fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1224dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1225fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(7, Operand(reg), imm);
1226fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1227fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1228fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1229dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg0, CpuRegister reg1) {
1230fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1231dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg0, reg1);
1232fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x3B);
1233dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg0.LowBits(), Operand(reg1));
1234fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1235fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1236fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1237dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg, const Address& address) {
1238fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1239dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1240fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x3B);
1241dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1242fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1243fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1244fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1245d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpl(const Address& address, CpuRegister reg) {
1246d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1247d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex32(reg, address);
1248d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x39);
1249d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOperand(reg.LowBits(), address);
1250d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1251d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1252d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1253d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpl(const Address& address, const Immediate& imm) {
1254d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1255d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex32(address);
1256d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitComplex(7, address, imm);
1257d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1258d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1259d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
12605a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::cmpq(CpuRegister reg0, CpuRegister reg1) {
12615a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12625a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(reg0, reg1);
12635a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x3B);
12645a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitOperand(reg0.LowBits(), Operand(reg1));
12655a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
12665a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
12675a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
126896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::cmpq(CpuRegister reg, const Immediate& imm) {
126996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
127096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  CHECK(imm.is_int32());  // cmpq only supports 32b immediate.
127196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(reg);
127296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitComplex(7, Operand(reg), imm);
127396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
127496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
127596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
127696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::cmpq(CpuRegister reg, const Address& address) {
127796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
127840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(reg, address);
127996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x3B);
128096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
128196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
128296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
128396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
1284d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpq(const Address& address, const Immediate& imm) {
1285d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  CHECK(imm.is_int32());  // cmpq only supports 32b immediate.
1286d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1287d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(address);
1288d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitComplex(7, address, imm);
1289d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1290d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1291d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1292dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister dst, CpuRegister src) {
1293fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1294dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1295fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x03);
1296dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
1297fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1298fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1299fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1300dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister reg, const Address& address) {
1301fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1302dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1303fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x03);
1304dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1305fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1306fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1307fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1308dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::testl(CpuRegister reg1, CpuRegister reg2) {
1309fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1310dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg1, reg2);
1311fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x85);
1312dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(reg1.LowBits(), reg2.LowBits());
1313fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1314fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1315fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1316cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravlevoid X86_64Assembler::testl(CpuRegister reg, const Address& address) {
1317cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1318cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitOptionalRex32(reg, address);
1319cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitUint8(0x85);
1320cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitOperand(reg.LowBits(), address);
1321cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle}
1322cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle
1323cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle
1324dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::testl(CpuRegister reg, const Immediate& immediate) {
1325fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1326fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // For registers that have a byte variant (RAX, RBX, RCX, and RDX)
1327dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // we only test the byte CpuRegister to keep the encoding short.
1328dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (immediate.is_uint8() && reg.AsRegister() < 4) {
1329fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use zero-extended 8-bit immediate.
1330dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    if (reg.AsRegister() == RAX) {
1331fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xA8);
1332fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1333fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xF6);
1334dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      EmitUint8(0xC0 + reg.AsRegister());
1335fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1336fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(immediate.value() & 0xFF);
1337dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  } else if (reg.AsRegister() == RAX) {
1338fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use short form if the destination is RAX.
1339fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xA9);
1340fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
1341fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1342dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitOptionalRex32(reg);
1343fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xF7);
1344fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(0, Operand(reg));
1345fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
1346fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1347fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1348fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1349fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1350d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::testq(CpuRegister reg1, CpuRegister reg2) {
1351d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1352d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(reg1, reg2);
1353d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x85);
1354d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRegisterOperand(reg1.LowBits(), reg2.LowBits());
1355d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1356d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1357d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1358f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffrayvoid X86_64Assembler::testq(CpuRegister reg, const Address& address) {
1359f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13607fd8b59ab9fcd896a95883ce7be781d74e849d60Mark Mendell  EmitRex64(reg, address);
1361f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitUint8(0x85);
1362f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
1363f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray}
1364f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1365f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1366dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::andl(CpuRegister dst, CpuRegister src) {
1367fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1368dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1369fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x23);
1370dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1371fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1372fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1373fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
13749574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::andl(CpuRegister reg, const Address& address) {
13759574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13769574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
13779574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x23);
13789574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
13799574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13809574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13819574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1382dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::andl(CpuRegister dst, const Immediate& imm) {
1383fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1384dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
1385fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(4, Operand(dst), imm);
1386fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1387fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1389412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffrayvoid X86_64Assembler::andq(CpuRegister reg, const Immediate& imm) {
1390412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1391412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  CHECK(imm.is_int32());  // andq only supports 32b immediate.
1392412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitRex64(reg);
1393412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitComplex(4, Operand(reg), imm);
1394412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray}
1395412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
1396412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
13979574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::andq(CpuRegister dst, CpuRegister src) {
13989574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13999574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitRex64(dst, src);
14009574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x23);
14019574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
14029574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14039574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14049574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
140540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::andq(CpuRegister dst, const Address& src) {
140640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
140740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(dst, src);
140840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x23);
140940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
141040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
141140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
141240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
1413dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::orl(CpuRegister dst, CpuRegister src) {
1414fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1415dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1416fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0B);
1417dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1418fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1419fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1420fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
14219574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::orl(CpuRegister reg, const Address& address) {
14229574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14239574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
14249574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x0B);
14259574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
14269574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14279574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14289574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1429dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::orl(CpuRegister dst, const Immediate& imm) {
1430fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1431dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
1432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(1, Operand(dst), imm);
1433fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
14363f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendellvoid X86_64Assembler::orq(CpuRegister dst, const Immediate& imm) {
14373f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14383f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  CHECK(imm.is_int32());  // orq only supports 32b immediate.
14393f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitRex64(dst);
14403f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitComplex(1, Operand(dst), imm);
14413f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell}
14423f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
14433f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
14449574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::orq(CpuRegister dst, CpuRegister src) {
14459574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14469574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitRex64(dst, src);
14479574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x0B);
14489574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
14499574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14509574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14519574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
145240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::orq(CpuRegister dst, const Address& src) {
145340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
145440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(dst, src);
145540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0B);
145640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
145740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
145840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
145940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
1460dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xorl(CpuRegister dst, CpuRegister src) {
1461fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1462dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1463fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x33);
1464dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1465fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
14675a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14689574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::xorl(CpuRegister reg, const Address& address) {
14699574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14709574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
14719574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x33);
14729574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
14739574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14749574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14759574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14769574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::xorl(CpuRegister dst, const Immediate& imm) {
14779574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14789574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(dst);
14799574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitComplex(6, Operand(dst), imm);
14809574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14819574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14829574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1483412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffrayvoid X86_64Assembler::xorq(CpuRegister dst, CpuRegister src) {
1484412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1485412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitRex64(dst, src);
1486412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitUint8(0x33);
1487412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
1488412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray}
1489412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
1490412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
14915a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::xorq(CpuRegister dst, const Immediate& imm) {
14925a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14935a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // xorq only supports 32b immediate.
14945a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(dst);
14955a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitComplex(6, Operand(dst), imm);
14965a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
14975a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
149840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::xorq(CpuRegister dst, const Address& src) {
149940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
150040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(dst, src);
150140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x33);
150240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
150340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
150440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
150540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
1506dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#if 0
1507dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::rex(bool force, bool w, Register* r, Register* x, Register* b) {
1508fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // REX.WRXB
1509fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // W - 64-bit operand
1510fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // R - MODRM.reg
1511fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // X - SIB.index
1512fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // B - MODRM.rm/SIB.base
1513dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = force ? 0x40 : 0;
1514dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
1515fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x48;  // REX.W000
1516fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1517dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (r != nullptr && *r >= Register::R8 && *r < Register::kNumberOfCpuRegisters) {
1518fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x44;  // REX.0R00
1519dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *r = static_cast<Register>(*r - 8);
1520fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1521dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (x != nullptr && *x >= Register::R8 && *x < Register::kNumberOfCpuRegisters) {
1522dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x42;  // REX.00X0
1523dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *x = static_cast<Register>(*x - 8);
1524dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1525dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (b != nullptr && *b >= Register::R8 && *b < Register::kNumberOfCpuRegisters) {
1526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x41;  // REX.000B
1527dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *b = static_cast<Register>(*b - 8);
1528fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1529fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (rex != 0) {
1530fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(rex);
1531fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1532fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1533fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1534dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::rex_reg_mem(bool force, bool w, Register* dst, const Address& mem) {
1535dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // REX.WRXB
1536dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // W - 64-bit operand
1537dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // R - MODRM.reg
1538dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // X - SIB.index
1539dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // B - MODRM.rm/SIB.base
1540dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = mem->rex();
1541dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (force) {
1542dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x40;  // REX.0000
1543dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1544dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
1545dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x48;  // REX.W000
1546dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1547dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (dst != nullptr && *dst >= Register::R8 && *dst < Register::kNumberOfCpuRegisters) {
1548dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x44;  // REX.0R00
1549dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *dst = static_cast<Register>(*dst - 8);
1550dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1551dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (rex != 0) {
1552dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitUint8(rex);
1553dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1554dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
1555dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1556dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid rex_mem_reg(bool force, bool w, Address* mem, Register* src);
1557dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#endif
1558dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1559dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister reg, const Immediate& imm) {
1560fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1561dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1562fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, Operand(reg), imm);
1563fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1564fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1565fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1566dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addq(CpuRegister reg, const Immediate& imm) {
1567fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
15685a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // addq only supports 32b immediate.
1569dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(reg);
1570fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, Operand(reg), imm);
1571fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1572fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1573fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
157496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::addq(CpuRegister dst, const Address& address) {
157596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
15767fd8b59ab9fcd896a95883ce7be781d74e849d60Mark Mendell  EmitRex64(dst, address);
157796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x03);
157896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(dst.LowBits(), address);
157996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
158096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
158196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
15825a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::addq(CpuRegister dst, CpuRegister src) {
15835a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
15845a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // 0x01 is addq r/m64 <- r/m64 + r64, with op1 in r/m and op2 in reg: so reverse EmitRex64
15855a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(src, dst);
15865a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x01);
15875a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
15885a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
15895a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
15905a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1591dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(const Address& address, CpuRegister reg) {
1592fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1593dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1594fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x01);
1595dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1596fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1597fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1598fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1599fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addl(const Address& address, const Immediate& imm) {
1600fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1601dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1602fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, address, imm);
1603fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1604fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1605fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1606dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister dst, CpuRegister src) {
1607fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1608dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1609fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2B);
1610dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1611fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1612fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1613fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1614dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister reg, const Immediate& imm) {
1615fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1616dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1617fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(5, Operand(reg), imm);
1618fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1619fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1620fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
16215a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::subq(CpuRegister reg, const Immediate& imm) {
16225a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16235a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // subq only supports 32b immediate.
16245a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(reg);
16255a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitComplex(5, Operand(reg), imm);
16265a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
16275a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
16285a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
16295a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::subq(CpuRegister dst, CpuRegister src) {
16305a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16315a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(dst, src);
16325a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x2B);
16335a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRegisterOperand(dst.LowBits(), src.LowBits());
16345a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
16355a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
16365a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
163796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::subq(CpuRegister reg, const Address& address) {
163896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16397fd8b59ab9fcd896a95883ce7be781d74e849d60Mark Mendell  EmitRex64(reg, address);
164096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x2B);
164196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(reg.LowBits() & 7, address);
164296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
164396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
164496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
1645dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister reg, const Address& address) {
1646fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1647dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1648fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2B);
1649dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1651fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1653fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cdq() {
1654fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1655fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x99);
1656fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1657fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1658fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1659d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cqo() {
1660d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1661d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64();
1662d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x99);
1663d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1664d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1665d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1666dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::idivl(CpuRegister reg) {
1667fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1668dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1669fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1670dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xF8 | reg.LowBits());
1671fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1672fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1673fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1674d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::idivq(CpuRegister reg) {
1675d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1676d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(reg);
1677d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0xF7);
1678d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0xF8 | reg.LowBits());
1679d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1680d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1681d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1682dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister dst, CpuRegister src) {
1683fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1684dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1685fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1686fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAF);
1687dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1688fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1689fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
16904a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendellvoid X86_64Assembler::imull(CpuRegister dst, CpuRegister src, const Immediate& imm) {
1691fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1692851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  CHECK(imm.is_int32());  // imull only supports 32b immediate.
1693851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
16944a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell  EmitOptionalRex32(dst, src);
1695851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1696851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // See whether imm can be represented as a sign-extended 8bit value.
1697851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  int32_t v32 = static_cast<int32_t>(imm.value());
1698ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  if (IsInt<8>(v32)) {
1699851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Sign-extension works.
1700851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x6B);
17014a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell    EmitOperand(dst.LowBits(), Operand(src));
1702851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(static_cast<uint8_t>(v32 & 0xFF));
1703851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
1704851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Not representable, use full immediate.
1705851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x69);
17064a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell    EmitOperand(dst.LowBits(), Operand(src));
1707851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitImmediate(imm);
1708851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1709fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1710fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1711fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
17124a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendellvoid X86_64Assembler::imull(CpuRegister reg, const Immediate& imm) {
17134a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell  imull(reg, reg, imm);
17144a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell}
17154a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell
17164a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell
1717dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg, const Address& address) {
1718fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1719dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1720fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1721fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAF);
1722dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1723fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1724fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1725fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
172634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister dst, CpuRegister src) {
172734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
172834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRex64(dst, src);
172934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0x0F);
173034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0xAF);
173134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRegisterOperand(dst.LowBits(), src.LowBits());
173234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
173334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
173434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
173534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister reg, const Immediate& imm) {
17363f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  imulq(reg, reg, imm);
17373f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell}
17383f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
17393f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendellvoid X86_64Assembler::imulq(CpuRegister dst, CpuRegister reg, const Immediate& imm) {
174034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
174134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  CHECK(imm.is_int32());  // imulq only supports 32b immediate.
1742851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
17433f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitRex64(dst, reg);
1744851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1745851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // See whether imm can be represented as a sign-extended 8bit value.
1746851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  int64_t v64 = imm.value();
1747ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  if (IsInt<8>(v64)) {
1748851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Sign-extension works.
1749851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x6B);
17503f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell    EmitOperand(dst.LowBits(), Operand(reg));
1751851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(static_cast<uint8_t>(v64 & 0xFF));
1752851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
1753851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Not representable, use full immediate.
1754851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x69);
17553f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell    EmitOperand(dst.LowBits(), Operand(reg));
1756851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitImmediate(imm);
1757851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
175834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
175934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
176034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister reg, const Address& address) {
176134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
176234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRex64(reg, address);
176334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0x0F);
176434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0xAF);
176534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitOperand(reg.LowBits(), address);
176634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
176734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
176834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
1769dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg) {
1770fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1771dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1772fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1773fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, Operand(reg));
1774fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1775fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1776fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
17770f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchezvoid X86_64Assembler::imulq(CpuRegister reg) {
17780f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
17790f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitRex64(reg);
17800f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitUint8(0xF7);
17810f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitOperand(5, Operand(reg));
17820f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez}
17830f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez
17840f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez
1785fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::imull(const Address& address) {
1786fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1787dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1788fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1789fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, address);
1790fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1791fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1792fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1793dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::mull(CpuRegister reg) {
1794fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1795dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1796fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1797fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, Operand(reg));
1798fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1799fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1800fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1801fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mull(const Address& address) {
1802fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1803dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1804fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1805fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, address);
1806fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1807fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1808fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1809dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shll(CpuRegister reg, const Immediate& imm) {
18101a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 4, reg, imm);
1811fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1812fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1813fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
18149aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shlq(CpuRegister reg, const Immediate& imm) {
18159aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 4, reg, imm);
18169aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18179aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18189aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
1819dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shll(CpuRegister operand, CpuRegister shifter) {
18209aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 4, operand, shifter);
18219aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18229aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18239aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18249aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shlq(CpuRegister operand, CpuRegister shifter) {
18259aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 4, operand, shifter);
1826fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1827fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1828fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1829dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shrl(CpuRegister reg, const Immediate& imm) {
18301a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 5, reg, imm);
18311a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray}
18321a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray
18331a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray
18341a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffrayvoid X86_64Assembler::shrq(CpuRegister reg, const Immediate& imm) {
18351a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(true, 5, reg, imm);
1836fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1837fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1838fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1839dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shrl(CpuRegister operand, CpuRegister shifter) {
18409aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 5, operand, shifter);
18419aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18429aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18439aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18449aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shrq(CpuRegister operand, CpuRegister shifter) {
18459aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 5, operand, shifter);
1846fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1849dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::sarl(CpuRegister reg, const Immediate& imm) {
18501a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 7, reg, imm);
1851fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1852fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1854dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::sarl(CpuRegister operand, CpuRegister shifter) {
18559aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 7, operand, shifter);
18569aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18579aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18589aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18599aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::sarq(CpuRegister reg, const Immediate& imm) {
18609aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 7, reg, imm);
18619aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18629aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18639aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18649aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::sarq(CpuRegister operand, CpuRegister shifter) {
18659aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 7, operand, shifter);
1866fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1867fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1868fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1869dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::negl(CpuRegister reg) {
1870fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1871dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1872fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1873fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, Operand(reg));
1874fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1875fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1876705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
18772e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillainvoid X86_64Assembler::negq(CpuRegister reg) {
18782e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
18792e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitRex64(reg);
18802e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitUint8(0xF7);
18812e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitOperand(3, Operand(reg));
18822e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain}
18832e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain
1884fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1885dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::notl(CpuRegister reg) {
1886fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1887dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1888fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1889dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xD0 | reg.LowBits());
1890fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1891fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1892fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1893705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillainvoid X86_64Assembler::notq(CpuRegister reg) {
1894705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1895705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitRex64(reg);
1896705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitUint8(0xF7);
1897705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitOperand(2, Operand(reg));
1898705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain}
1899705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
1900705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
1901fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::enter(const Immediate& imm) {
1902fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1903fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC8);
1904ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  CHECK(imm.is_uint16()) << imm.value();
1905fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
1906fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8((imm.value() >> 8) & 0xFF);
1907fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x00);
1908fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1909fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1910fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1911fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::leave() {
1912fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1913fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC9);
1914fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1915fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1916fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1917fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ret() {
1918fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1919fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC3);
1920fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1921fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1922fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1923fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ret(const Immediate& imm) {
1924fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1925fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC2);
1926fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_uint16());
1927fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
1928fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8((imm.value() >> 8) & 0xFF);
1929fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1930fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1931fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1932fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1933fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::nop() {
1934fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1935fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x90);
1936fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1937fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1938fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1939fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::int3() {
1940fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1941fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xCC);
1942fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1943fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1944fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1945fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::hlt() {
1946fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1947fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF4);
1948fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1949fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1950fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1951fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::j(Condition condition, Label* label) {
1952fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1953fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
1954fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kShortSize = 2;
1955fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kLongSize = 6;
1956fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
1957fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
1958ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe    if (IsInt<8>(offset - kShortSize)) {
1959fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x70 + condition);
1960fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8((offset - kShortSize) & 0xFF);
1961fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1962fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x0F);
1963fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x80 + condition);
1964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitInt32(offset - kLongSize);
1965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1966fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1967fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x0F);
1968fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x80 + condition);
1969fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
1970fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1971fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1972fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1973fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1974dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::jmp(CpuRegister reg) {
1975fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1976dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1977fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1978dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(4, reg.LowBits());
1979fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1980fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1981fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::jmp(const Address& address) {
1982fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1983dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1984fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1985fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, address);
1986fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1987fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1988fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::jmp(Label* label) {
1989fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1990fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
1991fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kShortSize = 2;
1992fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kLongSize = 5;
1993fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
1994fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
1995ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe    if (IsInt<8>(offset - kShortSize)) {
1996fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xEB);
1997fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8((offset - kShortSize) & 0xFF);
1998fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1999fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xE9);
2000fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitInt32(offset - kLongSize);
2001fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2002fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xE9);
2004fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
2005fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2006fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2007fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2008fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2009b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendellvoid X86_64Assembler::rep_movsw() {
2010b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2011b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell  EmitUint8(0x66);
2012b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell  EmitUint8(0xF3);
2013b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell  EmitUint8(0xA5);
2014b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell}
2015b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell
2016b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell
2017fca82208f7128fcda09b6a4743199308332558a2Dmitry PetrochenkoX86_64Assembler* X86_64Assembler::lock() {
2018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2019fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF0);
2020fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return this;
2021fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2022fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2023fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2024dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpxchgl(const Address& address, CpuRegister reg) {
2025fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
202658d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitOptionalRex32(reg, address);
202758d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitUint8(0x0F);
202858d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitUint8(0xB1);
202958d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitOperand(reg.LowBits(), address);
203058d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell}
203158d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
203258d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
203358d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendellvoid X86_64Assembler::cmpxchgq(const Address& address, CpuRegister reg) {
203458d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
203558d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitRex64(reg, address);
2036fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
2037fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB1);
2038dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
2039fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2040fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
204158d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
2042fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mfence() {
2043fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2044fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
2045fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAE);
2046fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF0);
2047fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2048fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
20495a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
2050fca82208f7128fcda09b6a4743199308332558a2Dmitry PetrochenkoX86_64Assembler* X86_64Assembler::gs() {
20515a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // TODO: gs is a prefix and not an instruction
2052fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2053fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x65);
2054fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return this;
2055fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2056fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
20575a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
2058dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::AddImmediate(CpuRegister reg, const Immediate& imm) {
2059fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int value = imm.value();
2060dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (value != 0) {
2061dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    if (value > 0) {
2062fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      addl(reg, imm);
2063dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    } else {
2064fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      subl(reg, Immediate(value));
2065fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2066fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2067fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2068fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2069fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
20705a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::setcc(Condition condition, CpuRegister dst) {
20715a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
20725a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // RSP, RBP, RDI, RSI need rex prefix (else the pattern encodes ah/bh/ch/dh).
20735a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (dst.NeedsRex() || dst.AsRegister() > 3) {
20745a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitOptionalRex(true, false, false, false, dst.NeedsRex());
20755a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
20765a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x0F);
20775a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x90 + condition);
20785a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0xC0 + dst.LowBits());
20795a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
20805a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
208171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::bswapl(CpuRegister dst) {
208271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
208371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, false, false, false, dst.NeedsRex());
208471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
208571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0xC8 + dst.LowBits());
208671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
208771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
208871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::bswapq(CpuRegister dst) {
208971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
209071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, true, false, false, dst.NeedsRex());
209171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
209271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0xC8 + dst.LowBits());
209371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
209471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
20958ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendellvoid X86_64Assembler::bsrl(CpuRegister dst, CpuRegister src) {
20968ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
20978ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitOptionalRex32(dst, src);
20988ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0x0F);
20998ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0xBD);
21008ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitRegisterOperand(dst.LowBits(), src.LowBits());
21018ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell}
21028ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell
21038ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendellvoid X86_64Assembler::bsrl(CpuRegister dst, const Address& src) {
21048ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
21058ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitOptionalRex32(dst, src);
21068ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0x0F);
21078ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0xBD);
21088ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitOperand(dst.LowBits(), src);
21098ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell}
21108ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell
21118ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendellvoid X86_64Assembler::bsrq(CpuRegister dst, CpuRegister src) {
21128ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
21138ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitRex64(dst, src);
21148ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0x0F);
21158ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0xBD);
21168ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitRegisterOperand(dst.LowBits(), src.LowBits());
21178ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell}
21188ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell
21198ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendellvoid X86_64Assembler::bsrq(CpuRegister dst, const Address& src) {
21208ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
21218ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitRex64(dst, src);
21228ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0x0F);
21238ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0xBD);
21248ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitOperand(dst.LowBits(), src);
21258ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell}
21265a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
212721030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampevoid X86_64Assembler::repne_scasw() {
212821030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
212921030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe  EmitUint8(0x66);
213021030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe  EmitUint8(0xF2);
213121030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe  EmitUint8(0xAF);
213221030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe}
213321030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe
213421030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe
213571311f868e2579fa5d40b24e620198734119d1a0agicsakivoid X86_64Assembler::repe_cmpsw() {
213671311f868e2579fa5d40b24e620198734119d1a0agicsaki  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
213771311f868e2579fa5d40b24e620198734119d1a0agicsaki  EmitUint8(0x66);
213871311f868e2579fa5d40b24e620198734119d1a0agicsaki  EmitUint8(0xF3);
213971311f868e2579fa5d40b24e620198734119d1a0agicsaki  EmitUint8(0xA7);
214071311f868e2579fa5d40b24e620198734119d1a0agicsaki}
214171311f868e2579fa5d40b24e620198734119d1a0agicsaki
214271311f868e2579fa5d40b24e620198734119d1a0agicsaki
2143970abfb65530b700f3a0cc8b90b131df5420cec3agicsakivoid X86_64Assembler::repe_cmpsl() {
2144970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2145970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki  EmitUint8(0xF3);
2146970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki  EmitUint8(0xA7);
2147970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki}
2148970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki
2149970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki
21503fd0e6a86430bf060c7eb391c1378394c4a2c574agicsakivoid X86_64Assembler::repe_cmpsq() {
21513fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
21523fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki  EmitUint8(0xF3);
21533fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki  EmitRex64();
21543fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki  EmitUint8(0xA7);
21553fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki}
21563fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki
21573fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki
2158fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
2159fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: Need to have a code constants table.
2160fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int64_t constant = bit_cast<int64_t, double>(value);
2161fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Immediate(High32Bits(constant)));
2162fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Immediate(Low32Bits(constant)));
2163dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movsd(dst, Address(CpuRegister(RSP), 0));
216413735955f39b3b304c37d2b2840663c131262c18Ian Rogers  addq(CpuRegister(RSP), Immediate(2 * sizeof(intptr_t)));
2165fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2166fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2167fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2168fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Align(int alignment, int offset) {
2169fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(IsPowerOfTwo(alignment));
2170fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit nop instruction until the real position is aligned.
2171fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) {
2172fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    nop();
2173fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2174fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2175fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2176fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2177fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Bind(Label* label) {
2178fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int bound = buffer_.Size();
2179fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(!label->IsBound());  // Labels can only be bound once.
2180fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  while (label->IsLinked()) {
2181fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int position = label->LinkPosition();
2182fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int next = buffer_.Load<int32_t>(position);
2183fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    buffer_.Store<int32_t>(position, bound - (position + 4));
2184fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    label->position_ = next;
2185fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2186fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  label->BindTo(bound);
2187fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2188fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2189fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2190dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOperand(uint8_t reg_or_opcode, const Operand& operand) {
2191fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GE(reg_or_opcode, 0);
2192fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(reg_or_opcode, 8);
2193fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  const int length = operand.length_;
2194fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GT(length, 0);
2195fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit the ModRM byte updated with the given reg value.
2196fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(operand.encoding_[0] & 0x38, 0);
2197fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(operand.encoding_[0] + (reg_or_opcode << 3));
2198fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit the rest of the encoded operand.
2199fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (int i = 1; i < length; i++) {
2200fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(operand.encoding_[i]);
2201fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2202f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  AssemblerFixup* fixup = operand.GetFixup();
2203f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  if (fixup != nullptr) {
2204f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    EmitFixup(fixup);
2205f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2206fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2207fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2208fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2209fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitImmediate(const Immediate& imm) {
22105a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (imm.is_int32()) {
22115a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt32(static_cast<int32_t>(imm.value()));
22125a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  } else {
22135a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt64(imm.value());
22145a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
2215fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2216fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2217fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2218dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitComplex(uint8_t reg_or_opcode,
2219dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                  const Operand& operand,
2220dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                  const Immediate& immediate) {
2221fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GE(reg_or_opcode, 0);
2222fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(reg_or_opcode, 8);
2223fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (immediate.is_int8()) {
2224fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use sign-extended 8-bit immediate.
2225fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x83);
2226fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, operand);
2227fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(immediate.value() & 0xFF);
2228dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  } else if (operand.IsRegister(CpuRegister(RAX))) {
2229fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use short form if the destination is eax.
2230fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x05 + (reg_or_opcode << 3));
2231fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
2232fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2233fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x81);
2234fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, operand);
2235fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
2236fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2237fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2238fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2239fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2240fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitLabel(Label* label, int instruction_size) {
2241fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
2242fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
2243fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
2244fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitInt32(offset - instruction_size);
2245fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2246fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
2247fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2248fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2249fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2250fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2251fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitLabelLink(Label* label) {
2252fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(!label->IsBound());
2253fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int position = buffer_.Size();
2254fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitInt32(label->position_);
2255fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  label->LinkTo(position);
2256fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2257fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2258fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
22591a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffrayvoid X86_64Assembler::EmitGenericShift(bool wide,
22601a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       int reg_or_opcode,
22611a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister reg,
22621a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       const Immediate& imm) {
2263fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2264fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_int8());
22651a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  if (wide) {
22661a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray    EmitRex64(reg);
2267851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
2268851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOptionalRex32(reg);
22691a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  }
2270fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (imm.value() == 1) {
2271fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xD1);
2272fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, Operand(reg));
2273fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2274fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xC1);
2275fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, Operand(reg));
2276fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(imm.value() & 0xFF);
2277fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2278fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2279fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2280fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
22819aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::EmitGenericShift(bool wide,
22829aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle                                       int reg_or_opcode,
22831a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister operand,
22841a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister shifter) {
2285fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2286dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CHECK_EQ(shifter.AsRegister(), RCX);
22879aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  if (wide) {
22889aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle    EmitRex64(operand);
22899aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  } else {
22909aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle    EmitOptionalRex32(operand);
22919aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  }
2292fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD3);
2293fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(reg_or_opcode, Operand(operand));
2294fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2295fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2296dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) {
2297dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // REX.WRXB
2298dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // W - 64-bit operand
2299dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // R - MODRM.reg
2300dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // X - SIB.index
2301dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // B - MODRM.rm/SIB.base
2302dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = force ? 0x40 : 0;
2303dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
2304dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x48;  // REX.W000
2305dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2306dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (r) {
2307dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x44;  // REX.0R00
2308dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2309dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (x) {
2310dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x42;  // REX.00X0
2311dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2312dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (b) {
2313dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x41;  // REX.000B
2314dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2315dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (rex != 0) {
2316dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitUint8(rex);
2317dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2318dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2319dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2320dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister reg) {
2321fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov  EmitOptionalRex(false, false, false, false, reg.NeedsRex());
2322dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2323dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2324dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, CpuRegister src) {
2325dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2326dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2327dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2328dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, XmmRegister src) {
2329dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2330dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2331dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2332dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, XmmRegister src) {
2333dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2334dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2335dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2336dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, CpuRegister src) {
2337dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2338dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2339dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2340dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(const Operand& operand) {
2341790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2342790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2343790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2344790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2345dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2346dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2347dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, const Operand& operand) {
2348790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2349790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2350790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2351790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2352790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2353790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2354790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2355dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2356dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2357dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, const Operand& operand) {
2358790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2359790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2360790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2361790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2362790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2363790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2364790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2365dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2366dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2367d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::EmitRex64() {
2368d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex(false, true, false, false, false);
2369d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
2370d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
2371dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister reg) {
2372fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov  EmitOptionalRex(false, true, false, false, reg.NeedsRex());
2373dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2374fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov
2375d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::EmitRex64(const Operand& operand) {
2376d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  uint8_t rex = operand.rex();
2377d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  rex |= 0x48;  // REX.W000
2378d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(rex);
2379d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
2380d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
2381dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister dst, CpuRegister src) {
2382dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2383dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2384dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2385102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffrayvoid X86_64Assembler::EmitRex64(XmmRegister dst, CpuRegister src) {
2386102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2387102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray}
2388102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray
2389624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainvoid X86_64Assembler::EmitRex64(CpuRegister dst, XmmRegister src) {
2390624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2391624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain}
2392624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
2393dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister dst, const Operand& operand) {
2394790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = 0x48 | operand.rex();  // REX.W000
2395790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2396790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2397790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
239840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(rex);
239940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
240040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
240140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::EmitRex64(XmmRegister dst, const Operand& operand) {
240240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  uint8_t rex = 0x48 | operand.rex();  // REX.W000
240340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  if (dst.NeedsRex()) {
240440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    rex |= 0x44;  // REX.0R00
2405790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
240640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(rex);
2407dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2408dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2409dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, CpuRegister src) {
2410d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // For src, SPL, BPL, SIL, DIL need the rex prefix.
2411d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  bool force = src.AsRegister() > 3;
2412d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex(force, false, dst.NeedsRex(), false, src.NeedsRex());
2413dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2414dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2415dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, const Operand& operand) {
2416d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  uint8_t rex = operand.rex();
2417d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // For dst, SPL, BPL, SIL, DIL need the rex prefix.
2418d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  bool force = dst.AsRegister() > 3;
2419d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  if (force) {
2420d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu    rex |= 0x40;  // REX.0000
2421d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  }
2422790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2423790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2424790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2425790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2426790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2427790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2428dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2429dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2430dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckystatic dwarf::Reg DWARFReg(Register reg) {
2431dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  return dwarf::Reg::X86_64Core(static_cast<int>(reg));
2432dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}
2433dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckystatic dwarf::Reg DWARFReg(FloatRegister reg) {
2434dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  return dwarf::Reg::X86_64Fp(static_cast<int>(reg));
2435dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}
2436dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
2437790a6b7312979513710c366b411ba6791ddf78c2Ian Rogersconstexpr size_t kFramePointerSize = 8;
2438790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers
2439fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
2440790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                                 const std::vector<ManagedRegister>& spill_regs,
2441790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                                 const ManagedRegisterEntrySpills& entry_spills) {
24428c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky  DCHECK_EQ(buffer_.Size(), 0U);  // Nothing emitted yet.
2443dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.SetCurrentCFAOffset(8);  // Return address on stack.
2444fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(frame_size, kStackAlignment);
2445c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int gpr_count = 0;
2446fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (int i = spill_regs.size() - 1; i >= 0; --i) {
2447c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2448c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsCpuRegister()) {
2449c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      pushq(spill.AsCpuRegister());
2450c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      gpr_count++;
2451dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.AdjustCFAOffset(kFramePointerSize);
2452dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.RelOffset(DWARFReg(spill.AsCpuRegister().AsRegister()), 0);
2453c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
24558c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky  // return address then method on stack.
2456c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t rest_of_frame = static_cast<int64_t>(frame_size)
2457c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov                          - (gpr_count * kFramePointerSize)
2458c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov                          - kFramePointerSize /*return address*/;
2459c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  subq(CpuRegister(RSP), Immediate(rest_of_frame));
2460dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(rest_of_frame);
2461547cdfd21ee21e4ab9ca8692d6ef47c62ee7ea52Tong Shen
2462c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  // spill xmms
2463c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t offset = rest_of_frame;
2464c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  for (int i = spill_regs.size() - 1; i >= 0; --i) {
2465c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2466c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsXmmRegister()) {
2467c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      offset -= sizeof(double);
2468c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      movsd(Address(CpuRegister(RSP), offset), spill.AsXmmRegister());
2469dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.RelOffset(DWARFReg(spill.AsXmmRegister().AsFloatRegister()), offset);
2470c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2471c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  }
2472cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe
2473e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK_EQ(kX86_64PointerSize, kFramePointerSize);
2474c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov
2475e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  movq(Address(CpuRegister(RSP), 0), method_reg.AsX86_64().AsCpuRegister());
2476fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2477fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (size_t i = 0; i < entry_spills.size(); ++i) {
2478fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    ManagedRegisterSpill spill = entry_spills.at(i);
2479fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (spill.AsX86_64().IsCpuRegister()) {
2480fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (spill.getSize() == 8) {
2481dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movq(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()),
2482dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers             spill.AsX86_64().AsCpuRegister());
2483fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2484fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(spill.getSize(), 4);
2485dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movl(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsCpuRegister());
2486fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2487fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2488fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (spill.getSize() == 8) {
2489dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movsd(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister());
2490fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2491fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(spill.getSize(), 4);
2492dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movss(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister());
2493fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2494fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2495fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2496fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2497fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2498fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::RemoveFrame(size_t frame_size,
2499fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                            const std::vector<ManagedRegister>& spill_regs) {
2500fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(frame_size, kStackAlignment);
2501dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.RememberState();
2502c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int gpr_count = 0;
2503c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  // unspill xmms
2504c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t offset = static_cast<int64_t>(frame_size) - (spill_regs.size() * kFramePointerSize) - 2 * kFramePointerSize;
2505fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (size_t i = 0; i < spill_regs.size(); ++i) {
2506c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2507c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsXmmRegister()) {
2508c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      offset += sizeof(double);
2509c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      movsd(spill.AsXmmRegister(), Address(CpuRegister(RSP), offset));
2510dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.Restore(DWARFReg(spill.AsXmmRegister().AsFloatRegister()));
2511c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    } else {
2512c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      gpr_count++;
2513c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2514c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  }
2515dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  int adjust = static_cast<int>(frame_size) - (gpr_count * kFramePointerSize) - kFramePointerSize;
2516dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  addq(CpuRegister(RSP), Immediate(adjust));
2517dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(-adjust);
2518c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  for (size_t i = 0; i < spill_regs.size(); ++i) {
2519c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2520c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsCpuRegister()) {
2521c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      popq(spill.AsCpuRegister());
2522dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.AdjustCFAOffset(-static_cast<int>(kFramePointerSize));
2523dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.Restore(DWARFReg(spill.AsCpuRegister().AsRegister()));
2524c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2525fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  ret();
2527dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  // The CFI should be restored for any code that follows the exit block.
2528dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.RestoreState();
2529dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.DefCFAOffset(frame_size);
2530fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2531fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2532fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::IncreaseFrameSize(size_t adjust) {
2533fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(adjust, kStackAlignment);
25345408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate  addq(CpuRegister(RSP), Immediate(-static_cast<int64_t>(adjust)));
2535dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(adjust);
2536fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2537fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2538fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::DecreaseFrameSize(size_t adjust) {
2539fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(adjust, kStackAlignment);
2540dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  addq(CpuRegister(RSP), Immediate(adjust));
2541dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(-adjust);
2542fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2543fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2544fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) {
2545fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2546fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (src.IsNoRegister()) {
2547fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2548fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsCpuRegister()) {
2549fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2550fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(4u, size);
2551dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movl(Address(CpuRegister(RSP), offs), src.AsCpuRegister());
2552fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2553fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(8u, size);
2554dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movq(Address(CpuRegister(RSP), offs), src.AsCpuRegister());
2555fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2556fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsRegisterPair()) {
2557fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2558dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(Address(CpuRegister(RSP), offs), src.AsRegisterPairLow());
2559dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(Address(CpuRegister(RSP), FrameOffset(offs.Int32Value()+4)),
2560fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko         src.AsRegisterPairHigh());
2561fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsX87Register()) {
2562fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2563dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fstps(Address(CpuRegister(RSP), offs));
2564fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2565dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fstpl(Address(CpuRegister(RSP), offs));
2566fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2567fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2568fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(src.IsXmmRegister());
2569fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2570dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movss(Address(CpuRegister(RSP), offs), src.AsXmmRegister());
2571fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2572dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movsd(Address(CpuRegister(RSP), offs), src.AsXmmRegister());
2573fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2574fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2576fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2577fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
2578fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2579fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(src.IsCpuRegister());
2580cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  movl(Address(CpuRegister(RSP), dest), src.AsCpuRegister());
2581fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2582fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2583fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
2584fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2585fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(src.IsCpuRegister());
2586dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), dest), src.AsCpuRegister());
2587fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2588fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2589fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
2590dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                            ManagedRegister) {
2591dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(Address(CpuRegister(RSP), dest), Immediate(imm));  // TODO(64) movq?
2592fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2593fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2594dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
2595dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                               ManagedRegister) {
2596fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movl(Address::Absolute(dest, true), Immediate(imm));  // TODO(64) movq?
2597fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2598fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2599dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreStackOffsetToThread64(ThreadOffset<8> thr_offs,
2600dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                 FrameOffset fr_offs,
2601dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                 ManagedRegister mscratch) {
2602fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2603fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2604dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), fr_offs));
2605fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister());
2606fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2607fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2608dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreStackPointerToThread64(ThreadOffset<8> thr_offs) {
2609dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(Address::Absolute(thr_offs, true), CpuRegister(RSP));
2610fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2611fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2612fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreSpanning(FrameOffset /*dst*/, ManagedRegister /*src*/,
2613fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                 FrameOffset /*in_off*/, ManagedRegister /*scratch*/) {
2614fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  UNIMPLEMENTED(FATAL);  // this case only currently exists for ARM
2615fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2616fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2617fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) {
2618fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2619fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (dest.IsNoRegister()) {
2620fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2621fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsCpuRegister()) {
2622fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2623fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(4u, size);
2624dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movl(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2626fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(8u, size);
2627dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2628fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2629fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsRegisterPair()) {
2630fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2631dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(dest.AsRegisterPairLow(), Address(CpuRegister(RSP), src));
2632dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(dest.AsRegisterPairHigh(), Address(CpuRegister(RSP), FrameOffset(src.Int32Value()+4)));
2633fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsX87Register()) {
2634fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2635dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      flds(Address(CpuRegister(RSP), src));
2636fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2637dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fldl(Address(CpuRegister(RSP), src));
2638fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2639fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2640fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(dest.IsXmmRegister());
2641fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2642dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), src));
2643fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2644dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), src));
2645fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2646fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2647fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2648fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2649dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) {
2650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2651fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (dest.IsNoRegister()) {
2652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2653fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsCpuRegister()) {
2654fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(4u, size);
2655dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    gs()->movl(dest.AsCpuRegister(), Address::Absolute(src, true));
2656fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsRegisterPair()) {
2657fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(8u, size);
2658fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    gs()->movq(dest.AsRegisterPairLow(), Address::Absolute(src, true));
2659fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsX87Register()) {
2660fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2661fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->flds(Address::Absolute(src, true));
2662fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2663fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->fldl(Address::Absolute(src, true));
2664fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2665fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2666fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(dest.IsXmmRegister());
2667fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2668fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->movss(dest.AsXmmRegister(), Address::Absolute(src, true));
2669fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2670fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->movsd(dest.AsXmmRegister(), Address::Absolute(src, true));
2671fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2672fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2673fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2674fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2675e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid X86_64Assembler::LoadRef(ManagedRegister mdest, FrameOffset src) {
2676fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2677fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister());
2678dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2679fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2680fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2681e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid X86_64Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs,
26824d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain                              bool unpoison_reference) {
2683fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2684fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
2685f889267adadd62c92d1d3726764598946a961c10Hiroshi Yamauchi  movl(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
26864d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain  if (unpoison_reference) {
26874d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain    MaybeUnpoisonHeapReference(dest.AsCpuRegister());
2688b88f0b16dbaff09a140d2a62b66eca2736ff514bHiroshi Yamauchi  }
2689fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2690fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2691fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
2692fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                              Offset offs) {
2693fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2694fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
2695fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
2696fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2697fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2698dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) {
2699fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2700fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister());
2701fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(dest.AsCpuRegister(), Address::Absolute(offs, true));
2702fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2703fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2704fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::SignExtend(ManagedRegister mreg, size_t size) {
2705fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister reg = mreg.AsX86_64();
2706fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(size == 1 || size == 2) << size;
2707fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(reg.IsCpuRegister()) << reg;
2708fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (size == 1) {
2709dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movsxb(reg.AsCpuRegister(), reg.AsCpuRegister());
2710fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2711fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    movsxw(reg.AsCpuRegister(), reg.AsCpuRegister());
2712fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2713fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2714fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2715fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ZeroExtend(ManagedRegister mreg, size_t size) {
2716fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister reg = mreg.AsX86_64();
2717fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(size == 1 || size == 2) << size;
2718fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(reg.IsCpuRegister()) << reg;
2719fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (size == 1) {
2720dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movzxb(reg.AsCpuRegister(), reg.AsCpuRegister());
2721fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2722fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    movzxw(reg.AsCpuRegister(), reg.AsCpuRegister());
2723fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2724fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2725fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2726fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
2727fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2728fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2729fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (!dest.Equals(src)) {
2730fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (dest.IsCpuRegister() && src.IsCpuRegister()) {
2731fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      movq(dest.AsCpuRegister(), src.AsCpuRegister());
2732fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else if (src.IsX87Register() && dest.IsXmmRegister()) {
2733fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      // Pass via stack and pop X87 register
2734dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      subl(CpuRegister(RSP), Immediate(16));
2735fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (size == 4) {
2736fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(src.AsX87Register(), ST0);
2737dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        fstps(Address(CpuRegister(RSP), 0));
2738dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0));
2739fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2740fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(src.AsX87Register(), ST0);
2741dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        fstpl(Address(CpuRegister(RSP), 0));
2742dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0));
2743fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2744dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      addq(CpuRegister(RSP), Immediate(16));
2745fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2746fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      // TODO: x87, SSE
2747fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      UNIMPLEMENTED(FATAL) << ": Move " << dest << ", " << src;
2748fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2749fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2750fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2751fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2752e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid X86_64Assembler::CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) {
2753fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2754fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2755dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), src));
2756dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(Address(CpuRegister(RSP), dest), scratch.AsCpuRegister());
2757fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2758fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2759dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CopyRawPtrFromThread64(FrameOffset fr_offs,
2760dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                             ThreadOffset<8> thr_offs,
2761dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                             ManagedRegister mscratch) {
2762fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2763fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2764fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(scratch.AsCpuRegister(), Address::Absolute(thr_offs, true));
2765fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Store(fr_offs, scratch, 8);
2766fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2767fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2768dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CopyRawPtrToThread64(ThreadOffset<8> thr_offs,
2769dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                           FrameOffset fr_offs,
2770dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                           ManagedRegister mscratch) {
2771fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2772fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2773fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Load(scratch, fr_offs, 8);
2774fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister());
2775fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2776fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2777e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid X86_64Assembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch,
2778e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           size_t size) {
2779fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2780fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (scratch.IsCpuRegister() && size == 8) {
2781fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, src, 4);
2782fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(dest, scratch, 4);
2783fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, FrameOffset(src.Int32Value() + 4), 4);
2784fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(FrameOffset(dest.Int32Value() + 4), scratch, 4);
2785fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2786fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, src, size);
2787fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(dest, scratch, size);
2788fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2789fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2790fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2791fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset /*dst*/, ManagedRegister /*src_base*/, Offset /*src_offset*/,
2792fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister /*scratch*/, size_t /*size*/) {
2793fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  UNIMPLEMENTED(FATAL);
2794fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2795fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2796fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
2797fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister scratch, size_t size) {
2798fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsNoRegister());
2799fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2800dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  pushq(Address(CpuRegister(RSP), src));
2801fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(dest_base.AsX86_64().AsCpuRegister(), dest_offset));
2802fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2803fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2804fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
2805fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch, size_t size) {
2806dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2807fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2808dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(scratch, Address(CpuRegister(RSP), src_base));
2809fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(scratch, Address(scratch, src_offset));
2810dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), dest), scratch);
2811fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2812fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2813fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(ManagedRegister dest, Offset dest_offset,
2814fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister src, Offset src_offset,
2815fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister scratch, size_t size) {
2816fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2817fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsNoRegister());
2818fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Address(src.AsX86_64().AsCpuRegister(), src_offset));
2819fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(dest.AsX86_64().AsCpuRegister(), dest_offset));
2820fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2821fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2822fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
2823fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch, size_t size) {
2824dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2825fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2826fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(dest.Int32Value(), src.Int32Value());
2827dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(scratch, Address(CpuRegister(RSP), src));
2828fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Address(scratch, src_offset));
2829fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(scratch, dest_offset));
2830fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2831fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2832fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::MemoryBarrier(ManagedRegister) {
2833fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  mfence();
2834fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2835fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2836eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::CreateHandleScopeEntry(ManagedRegister mout_reg,
2837eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                   FrameOffset handle_scope_offset,
2838fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   ManagedRegister min_reg, bool null_allowed) {
2839fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister out_reg = mout_reg.AsX86_64();
2840fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister in_reg = min_reg.AsX86_64();
2841fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (in_reg.IsNoRegister()) {  // TODO(64): && null_allowed
28422cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    // Use out_reg as indicator of null.
2843fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    in_reg = out_reg;
2844fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // TODO: movzwl
2845eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    movl(in_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2846fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(in_reg.IsCpuRegister());
2848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(out_reg.IsCpuRegister());
2849fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  VerifyObject(in_reg, null_allowed);
2850fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (null_allowed) {
2851fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Label null_arg;
2852fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (!out_reg.Equals(in_reg)) {
2853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
2854fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2855fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
2856fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    j(kZero, &null_arg);
2857eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2858fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Bind(&null_arg);
2859fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2860eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2861fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2862fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2863fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2864eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::CreateHandleScopeEntry(FrameOffset out_off,
2865eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                   FrameOffset handle_scope_offset,
2866fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   ManagedRegister mscratch,
2867fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   bool null_allowed) {
2868fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2869fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2870fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (null_allowed) {
2871fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Label null_arg;
2872eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2873fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    testl(scratch.AsCpuRegister(), scratch.AsCpuRegister());
2874fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    j(kZero, &null_arg);
2875eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2876fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Bind(&null_arg);
2877fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2878eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2879fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2880fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Store(out_off, scratch, 8);
2881fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2882fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2883eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Given a handle scope entry, load the associated reference.
2884eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::LoadReferenceFromHandleScope(ManagedRegister mout_reg,
2885fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                         ManagedRegister min_reg) {
2886fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister out_reg = mout_reg.AsX86_64();
2887fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister in_reg = min_reg.AsX86_64();
2888fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(out_reg.IsCpuRegister());
2889fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(in_reg.IsCpuRegister());
2890fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Label null_arg;
2891fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (!out_reg.Equals(in_reg)) {
2892fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
2893fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2894fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
2895fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  j(kZero, &null_arg);
2896fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(out_reg.AsCpuRegister(), Address(in_reg.AsCpuRegister(), 0));
2897fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Bind(&null_arg);
2898fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2899fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2900fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
2901fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: not validating references
2902fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2903fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2904fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
2905fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: not validating references
2906fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2907fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2908fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Call(ManagedRegister mbase, Offset offset, ManagedRegister) {
2909fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister base = mbase.AsX86_64();
2910fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(base.IsCpuRegister());
2911fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  call(Address(base.AsCpuRegister(), offset.Int32Value()));
2912fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: place reference map on call
2913fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2914fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2915fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) {
2916dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2917e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  movq(scratch, Address(CpuRegister(RSP), base));
2918fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  call(Address(scratch, offset));
2919fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2920fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2921dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CallFromThread64(ThreadOffset<8> offset, ManagedRegister /*mscratch*/) {
2922fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->call(Address::Absolute(offset, true));
2923fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2924fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2925fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::GetCurrentThread(ManagedRegister tr) {
2926dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(tr.AsX86_64().AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true));
2927fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2928fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2929dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::GetCurrentThread(FrameOffset offset, ManagedRegister mscratch) {
2930fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2931dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(scratch.AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true));
2932dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), offset), scratch.AsCpuRegister());
2933fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2934fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2935dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Slowpath entered when Thread::Current()->_exception is non-null
2936dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass X86_64ExceptionSlowPath FINAL : public SlowPath {
2937dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers public:
2938dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  explicit X86_64ExceptionSlowPath(size_t stack_adjust) : stack_adjust_(stack_adjust) {}
2939dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  virtual void Emit(Assembler *sp_asm) OVERRIDE;
2940dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers private:
2941dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  const size_t stack_adjust_;
2942dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers};
2943dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2944fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ExceptionPoll(ManagedRegister /*scratch*/, size_t stack_adjust) {
2945dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  X86_64ExceptionSlowPath* slow = new X86_64ExceptionSlowPath(stack_adjust);
2946fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  buffer_.EnqueueSlowPath(slow);
2947dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->cmpl(Address::Absolute(Thread::ExceptionOffset<8>(), true), Immediate(0));
2948fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  j(kNotEqual, slow->Entry());
2949fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2950fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2951dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64ExceptionSlowPath::Emit(Assembler *sasm) {
2952fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64Assembler* sp_asm = down_cast<X86_64Assembler*>(sasm);
2953fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#define __ sp_asm->
2954fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  __ Bind(&entry_);
2955fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Note: the return value is dead
2956fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (stack_adjust_ != 0) {  // Fix up the frame.
2957fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    __ DecreaseFrameSize(stack_adjust_);
2958fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2959dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Pass exception as argument in RDI
2960dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  __ gs()->movq(CpuRegister(RDI), Address::Absolute(Thread::ExceptionOffset<8>(), true));
2961dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(8, pDeliverException), true));
2962fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // this call should never return
2963fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  __ int3();
2964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#undef __
2965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2966fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2967f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellvoid X86_64Assembler::AddConstantArea() {
2968f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  const std::vector<int32_t>& area = constant_area_.GetBuffer();
296939dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell  for (size_t i = 0, e = area.size(); i < e; i++) {
2970f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2971f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    EmitInt32(area[i]);
2972f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2973f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2974f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2975f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddInt32(int32_t v) {
297639dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell  for (size_t i = 0, e = buffer_.size(); i < e; i++) {
2977f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    if (v == buffer_[i]) {
2978f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell      return i * elem_size_;
2979f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    }
2980f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2981f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2982f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Didn't match anything.
2983f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int result = buffer_.size() * elem_size_;
2984f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v);
2985f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return result;
2986f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2987f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2988f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddInt64(int64_t v) {
2989f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int32_t v_low = v;
2990f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int32_t v_high = v >> 32;
2991f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  if (buffer_.size() > 1) {
2992f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    // Ensure we don't pass the end of the buffer.
299339dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell    for (size_t i = 0, e = buffer_.size() - 1; i < e; i++) {
299439dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell      if (v_low == buffer_[i] && v_high == buffer_[i + 1]) {
2995f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell        return i * elem_size_;
2996f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell      }
2997f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    }
2998f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2999f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
3000f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Didn't match anything.
3001f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int result = buffer_.size() * elem_size_;
3002f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v_low);
3003f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v_high);
3004f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return result;
3005f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
3006f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
3007f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddDouble(double v) {
3008f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Treat the value as a 64-bit integer value.
3009f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return AddInt64(bit_cast<int64_t, double>(v));
3010f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
3011f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
3012f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddFloat(float v) {
3013f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Treat the value as a 32-bit integer value.
3014f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return AddInt32(bit_cast<int32_t, float>(v));
3015f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
3016f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
3017fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}  // namespace x86_64
3018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}  // namespace art
3019