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
226abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendellvoid X86_64Assembler::cmov(Condition c, CpuRegister dst, const Address& src, bool is64bit) {
227abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
228abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell  if (is64bit) {
229abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell    EmitRex64(dst, src);
230abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell  } else {
231abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell    EmitOptionalRex32(dst, src);
232abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell  }
233abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell  EmitUint8(0x0F);
234abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell  EmitUint8(0x40 + c);
235abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell  EmitOperand(dst.LowBits(), src);
236abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell}
237abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell
238abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell
239dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxb(CpuRegister dst, CpuRegister src) {
240fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
241dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(dst, src);
242fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
243fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB6);
244dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
245fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
246fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
247fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
248dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxb(CpuRegister dst, const Address& src) {
249fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
250d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // Byte register is only in the source register form, so we don't use
251d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // EmitOptionalByteRegNormalizingRex32(dst, src);
252d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex32(dst, src);
253fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
254fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB6);
255dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
256fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
257fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
258fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
259dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxb(CpuRegister dst, CpuRegister src) {
260fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
261dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(dst, src);
262fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
263fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBE);
264dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
265fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
266fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
267fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
268dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxb(CpuRegister dst, const Address& src) {
269fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
270d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // Byte register is only in the source register form, so we don't use
271d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // EmitOptionalByteRegNormalizingRex32(dst, src);
272d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex32(dst, src);
273fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
274fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBE);
275dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
276fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
277fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
278fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
279dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movb(CpuRegister /*dst*/, const Address& /*src*/) {
280fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  LOG(FATAL) << "Use movzxb or movsxb instead.";
281fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
282fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
283fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
284dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movb(const Address& dst, CpuRegister src) {
285fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
286dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(src, dst);
287fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x88);
288dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
289fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
290fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
291fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
292fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movb(const Address& dst, const Immediate& imm) {
293fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
29426a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOptionalRex32(dst);
295fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC6);
296dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(Register::RAX, dst);
297fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_int8());
298fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
299fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
300fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
301fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
302dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxw(CpuRegister dst, CpuRegister src) {
303fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
304dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
305fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
306fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB7);
307dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
308fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
309fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
310fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
311dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxw(CpuRegister dst, const Address& src) {
312fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
313dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
314fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
315fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB7);
316dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
317fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
318fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
319fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
320dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxw(CpuRegister dst, CpuRegister src) {
321fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
322dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
323fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
324fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBF);
325dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
326fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
327fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
328fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
329dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxw(CpuRegister dst, const Address& src) {
330fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
331dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
332fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
333fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBF);
334dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
335fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
336fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
337fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
338dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movw(CpuRegister /*dst*/, const Address& /*src*/) {
339fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  LOG(FATAL) << "Use movzxw or movsxw instead.";
340fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
341fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
342fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
343dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movw(const Address& dst, CpuRegister src) {
344fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
345fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperandSizeOverride();
346e4ded41ae2648973d5fed8c6bafaebf917ea7d17Nicolas Geoffray  EmitOptionalRex32(src, dst);
347fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
348dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
349fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
350fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
351fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
35226a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffrayvoid X86_64Assembler::movw(const Address& dst, const Immediate& imm) {
35326a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
35426a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOperandSizeOverride();
35526a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOptionalRex32(dst);
35626a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(0xC7);
35726a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOperand(Register::RAX, dst);
358b6e7206ad7a426adda9cfd649a4ef969607d79d6Nicolas Geoffray  CHECK(imm.is_uint16() || imm.is_int16());
35926a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(imm.value() & 0xFF);
36026a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(imm.value() >> 8);
36126a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray}
36226a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray
36326a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray
364dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::leaq(CpuRegister dst, const Address& src) {
365fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
366dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(dst, src);
367fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x8D);
368dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
369fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
370fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
371fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
372748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffrayvoid X86_64Assembler::leal(CpuRegister dst, const Address& src) {
373748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
374748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitOptionalRex32(dst, src);
375748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitUint8(0x8D);
376748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitOperand(dst.LowBits(), src);
377748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray}
378748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray
379748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray
3807fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffrayvoid X86_64Assembler::movaps(XmmRegister dst, XmmRegister src) {
3817fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3827fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitOptionalRex32(dst, src);
3837fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitUint8(0x0F);
3847fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitUint8(0x28);
385102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  EmitXmmRegisterOperand(dst.LowBits(), src);
3867fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray}
3877fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray
3887fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray
389fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(XmmRegister dst, const Address& src) {
390fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
391fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
392dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
393fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
394fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x10);
395dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
396fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
397fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
398fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
399fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(const Address& dst, XmmRegister src) {
400fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
401fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
402dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(src, dst);
403fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
404fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
405dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
406fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
407fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
408fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
409fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(XmmRegister dst, XmmRegister src) {
410fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
411fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
412851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);  // Movss is MR encoding instead of the usual RM.
413fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
414fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
415dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(src.LowBits(), dst);
416fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
417fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
418fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
419dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillainvoid X86_64Assembler::movsxd(CpuRegister dst, CpuRegister src) {
420dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
42157a88d4ac205874dc85d22f9f6a9ca3c4c373eebNicolas Geoffray  EmitRex64(dst, src);
422dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitUint8(0x63);
423dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitRegisterOperand(dst.LowBits(), src.LowBits());
424dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain}
425dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
426dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
427dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillainvoid X86_64Assembler::movsxd(CpuRegister dst, const Address& src) {
428dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
4297fd8b59ab9fcd896a95883ce7be781d74e849d60Mark Mendell  EmitRex64(dst, src);
430dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitUint8(0x63);
431dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitOperand(dst.LowBits(), src);
432dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain}
433dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
434dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
435dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movd(XmmRegister dst, CpuRegister src) {
43671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  movd(dst, src, true);
43771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
43871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
43971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(CpuRegister dst, XmmRegister src) {
44071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  movd(dst, src, true);
44171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
44271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
44371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(XmmRegister dst, CpuRegister src, bool is64bit) {
444fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
445fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
44671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, is64bit, dst.NeedsRex(), false, src.NeedsRex());
447fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
448fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x6E);
449dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
450fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
451fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
45271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(CpuRegister dst, XmmRegister src, bool is64bit) {
453fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
45571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, is64bit, src.NeedsRex(), false, dst.NeedsRex());
456fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
457fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x7E);
458dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), Operand(dst));
459fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
460fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
461fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
462fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addss(XmmRegister dst, XmmRegister src) {
463fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
464fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
465dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
467fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
468dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
469fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
470fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
471fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
472fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addss(XmmRegister dst, const Address& src) {
473fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
475dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
476fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
477fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
478dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
479fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
480fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
482fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subss(XmmRegister dst, XmmRegister src) {
483fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
484fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
485dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
486fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
487fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
488dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
489fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
490fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
491fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
492fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subss(XmmRegister dst, const Address& src) {
493fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
494fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
495dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
496fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
497fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
498dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
499fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
500fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
501fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
502fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulss(XmmRegister dst, XmmRegister src) {
503fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
504fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
505dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
506fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
507fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
508dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
509fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
510fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
511fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
512fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulss(XmmRegister dst, const Address& src) {
513fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
514fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
515dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
516fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
517fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
518dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
519fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
520fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
521fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
522fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divss(XmmRegister dst, XmmRegister src) {
523fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
524fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
525dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
527fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
528dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
529fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
530fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
531fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
532fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divss(XmmRegister dst, const Address& src) {
533fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
534fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
535dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
536fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
537fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
538dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
539fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
540fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
541fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
542fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::flds(const Address& src) {
543fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
544fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
545fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, src);
546fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
547fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
548fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
54924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fsts(const Address& dst) {
55024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
55124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xD9);
55224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitOperand(2, dst);
55324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
55424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
55524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
556fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fstps(const Address& dst) {
557fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
558fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
559fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
560fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
561fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
562fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
563fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(XmmRegister dst, const Address& src) {
564fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
565fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
566dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
567fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
568fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x10);
569dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
570fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
571fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
572fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
573fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(const Address& dst, XmmRegister src) {
574fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
576dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(src, dst);
577fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
578fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
579dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
580fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
581fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
582fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
583fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(XmmRegister dst, XmmRegister src) {
584fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
585fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
586851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);  // Movsd is MR encoding instead of the usual RM.
587fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
588fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
589dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(src.LowBits(), dst);
590fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
591fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
592fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
593fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addsd(XmmRegister dst, XmmRegister src) {
594fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
595fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
596dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
597fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
598fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
599dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
600fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
601fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
602fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
603fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addsd(XmmRegister dst, const Address& src) {
604fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
605fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
606dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
607fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
608fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
609dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
610fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
611fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
612fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
613fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subsd(XmmRegister dst, XmmRegister src) {
614fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
615fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
616dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
617fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
618fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
619dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
620fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
621fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
622fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
623fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subsd(XmmRegister dst, const Address& src) {
624fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
626dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
627fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
628fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
629dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
630fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
631fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
632fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
633fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulsd(XmmRegister dst, XmmRegister src) {
634fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
635fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
636dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
637fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
638fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
639dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
640fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
641fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
642fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
643fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulsd(XmmRegister dst, const Address& src) {
644fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
645fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
646dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
647fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
648fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
649dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
651fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
653fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divsd(XmmRegister dst, XmmRegister src) {
654fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
655fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
656dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
657fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
658fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
659dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
660fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
661fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
662fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
663fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divsd(XmmRegister dst, const Address& src) {
664fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
665fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
666dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
667fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
668fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
669dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
670fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
671fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
672fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
673dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src) {
6746d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  cvtsi2ss(dst, src, false);
6756d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain}
6766d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain
6776d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain
6786d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillainvoid X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src, bool is64bit) {
679fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
680fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
6816d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  if (is64bit) {
6826d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
6836d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    EmitRex64(dst, src);
6846d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  } else {
6856d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    EmitOptionalRex32(dst, src);
6866d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  }
687fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
688fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2A);
689dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
690fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
691fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
692fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
69340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::cvtsi2ss(XmmRegister dst, const Address& src, bool is64bit) {
69440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
69540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xF3);
69640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  if (is64bit) {
69740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    // Emit a REX.W prefix if the operand size is 64 bits.
69840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    EmitRex64(dst, src);
69940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  } else {
70040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    EmitOptionalRex32(dst, src);
70140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  }
70240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
70340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2A);
70440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
70540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
70640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
70740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
708dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsi2sd(XmmRegister dst, CpuRegister src) {
709647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  cvtsi2sd(dst, src, false);
710647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain}
711647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain
712647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain
713647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillainvoid X86_64Assembler::cvtsi2sd(XmmRegister dst, CpuRegister src, bool is64bit) {
714fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
715fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
716647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  if (is64bit) {
717647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
718647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    EmitRex64(dst, src);
719647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  } else {
720647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    EmitOptionalRex32(dst, src);
721647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  }
722fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
723fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2A);
724dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
725fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
726fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
727fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
72840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::cvtsi2sd(XmmRegister dst, const Address& src, bool is64bit) {
72940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
73040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xF2);
73140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  if (is64bit) {
73240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    // Emit a REX.W prefix if the operand size is 64 bits.
73340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    EmitRex64(dst, src);
73440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  } else {
73540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    EmitOptionalRex32(dst, src);
73640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  }
73740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
73840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2A);
73940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
74040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
74140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
74240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
743dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtss2si(CpuRegister dst, XmmRegister src) {
744fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
745fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
746dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
747fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
748fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2D);
749dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
750fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
751fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
752fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
753fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) {
754fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
755fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
756dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
757fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
758fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5A);
759dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
760fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
761fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
762fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
76340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::cvtss2sd(XmmRegister dst, const Address& src) {
76440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
76540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xF3);
76640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(dst, src);
76740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
76840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x5A);
76940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
77040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
77140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
77240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
773dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsd2si(CpuRegister dst, XmmRegister src) {
774fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
775fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
776dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
777fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
778fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2D);
779dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
780fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
781fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
782fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
783dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvttss2si(CpuRegister dst, XmmRegister src) {
784624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  cvttss2si(dst, src, false);
785624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain}
786624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
787624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
788624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainvoid X86_64Assembler::cvttss2si(CpuRegister dst, XmmRegister src, bool is64bit) {
789fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
790fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
791624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  if (is64bit) {
792624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
793624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    EmitRex64(dst, src);
794624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  } else {
795624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    EmitOptionalRex32(dst, src);
796624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  }
797fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
798fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2C);
799dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
800fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
801fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
802fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
803dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvttsd2si(CpuRegister dst, XmmRegister src) {
8044c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  cvttsd2si(dst, src, false);
8054c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain}
8064c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain
8074c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain
8084c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillainvoid X86_64Assembler::cvttsd2si(CpuRegister dst, XmmRegister src, bool is64bit) {
809fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
810fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
8114c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  if (is64bit) {
8124c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
8134c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    EmitRex64(dst, src);
8144c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  } else {
8154c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    EmitOptionalRex32(dst, src);
8164c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  }
817fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
818fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2C);
819dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
820fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
821fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
822fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
823fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) {
824fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
825fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
826dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
827fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
828fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5A);
829dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
830fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
831fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
832fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
83340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::cvtsd2ss(XmmRegister dst, const Address& src) {
83440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
83540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0xF2);
83640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(dst, src);
83740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
83840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x5A);
83940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
84040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
84140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
84240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
843fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) {
844fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
845fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
846dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xE6);
849dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
850fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
851fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
852fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::comiss(XmmRegister a, XmmRegister b) {
854fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
855dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(a, b);
856fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
857fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2F);
858dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(a.LowBits(), b);
859fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
860fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
861fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
86240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::comiss(XmmRegister a, const Address& b) {
86340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
86440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(a, b);
86540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
86640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2F);
86740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(a.LowBits(), b);
86840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
86940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
87040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
871fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::comisd(XmmRegister a, XmmRegister b) {
872fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
873fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
874dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(a, b);
875fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
876fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2F);
877dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(a.LowBits(), b);
878fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
879fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
88040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
88140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::comisd(XmmRegister a, const Address& b) {
88240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
88340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x66);
88440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(a, b);
88540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
88640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2F);
88740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(a.LowBits(), b);
88840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
88940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
89040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
891ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravlevoid X86_64Assembler::ucomiss(XmmRegister a, XmmRegister b) {
892ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
893ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitOptionalRex32(a, b);
894ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x0F);
895ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x2E);
896ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitXmmRegisterOperand(a.LowBits(), b);
897ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle}
898ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
899ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
90040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::ucomiss(XmmRegister a, const Address& b) {
90140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
90240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(a, b);
90340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
90440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2E);
90540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(a.LowBits(), b);
90640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
90740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
90840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
909ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravlevoid X86_64Assembler::ucomisd(XmmRegister a, XmmRegister b) {
910ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
911ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x66);
912ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitOptionalRex32(a, b);
913ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x0F);
914ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x2E);
915ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitXmmRegisterOperand(a.LowBits(), b);
916ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle}
917ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
918fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
91940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::ucomisd(XmmRegister a, const Address& b) {
92040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
92140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x66);
92240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOptionalRex32(a, b);
92340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0F);
92440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x2E);
92540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(a.LowBits(), b);
92640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
92740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
92840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
929fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendellvoid X86_64Assembler::roundsd(XmmRegister dst, XmmRegister src, const Immediate& imm) {
930fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
931fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x66);
932fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitOptionalRex32(dst, src);
933fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0F);
934fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x3A);
935fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0B);
936fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitXmmRegisterOperand(dst.LowBits(), src);
937fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(imm.value());
938fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell}
939fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
940fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
941fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendellvoid X86_64Assembler::roundss(XmmRegister dst, XmmRegister src, const Immediate& imm) {
942fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
943fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x66);
944fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitOptionalRex32(dst, src);
945fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0F);
946fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x3A);
947fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0A);
948fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitXmmRegisterOperand(dst.LowBits(), src);
949fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(imm.value());
950fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell}
951fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
952fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
953fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
954fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
955fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
956dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
957fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
958fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x51);
959dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
960fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
961fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
962fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
963fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::sqrtss(XmmRegister dst, XmmRegister src) {
964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
966dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
967fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
968fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x51);
969dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
970fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
971fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
972fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
973fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorpd(XmmRegister dst, const Address& src) {
974fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
975fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
976dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
977fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
978fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
979dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
980fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
981fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
982fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
983fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorpd(XmmRegister dst, XmmRegister src) {
984fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
985fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
986dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
987fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
988fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
989dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
990fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
991fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
992fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
993fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorps(XmmRegister dst, const Address& src) {
994fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
995dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
996fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
997fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
998dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
999fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1000fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1001fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1002fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorps(XmmRegister dst, XmmRegister src) {
1003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1004dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1005fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1006fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
1007dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
1008fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1009fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1010fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1011fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::andpd(XmmRegister dst, const Address& src) {
1012fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1013fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
1014dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1015fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1016fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x54);
1017dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
1018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1019fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
102071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::andpd(XmmRegister dst, XmmRegister src) {
102171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
102271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x66);
102371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
102471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
102571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x54);
102671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
102771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
102871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
102971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::andps(XmmRegister dst, XmmRegister src) {
103071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
103171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
103271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
103371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x54);
103471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
103571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
103671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
103771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::orpd(XmmRegister dst, XmmRegister src) {
103871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
103971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x66);
104071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
104171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
104271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x56);
104371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
104471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
104571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
104671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::orps(XmmRegister dst, XmmRegister src) {
104771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
104871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
104971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
105071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x56);
105171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
105271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
1053fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1054fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fldl(const Address& src) {
1055fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1056fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
1057fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, src);
1058fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1059fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1060fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
106124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fstl(const Address& dst) {
106224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
106324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDD);
106424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitOperand(2, dst);
106524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
106624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
106724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
1068fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fstpl(const Address& dst) {
1069fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1070fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
1071fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
1072fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1073fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1074fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
107524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fstsw() {
107624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
107724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0x9B);
107824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDF);
107924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xE0);
108024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
108124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
108224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
1083fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fnstcw(const Address& dst) {
1084fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1085fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1086fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(7, dst);
1087fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1088fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1089fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1090fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fldcw(const Address& src) {
1091fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1092fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1093fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, src);
1094fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1095fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1096fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1097fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fistpl(const Address& dst) {
1098fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1099fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDF);
1100fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(7, dst);
1101fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1102fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1103fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1104fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fistps(const Address& dst) {
1105fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1106fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDB);
1107fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
1108fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1109fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1110fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1111fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fildl(const Address& src) {
1112fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1113fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDF);
1114fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, src);
1115fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1116fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1117fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
11180a18601f141d864a26d4b74ff5613e69ae411483Roland Levillainvoid X86_64Assembler::filds(const Address& src) {
11190a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
11200a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  EmitUint8(0xDB);
11210a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  EmitOperand(0, src);
11220a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain}
11230a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain
11240a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain
1125fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fincstp() {
1126fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1127fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1128fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1129fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1130fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1131fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1132fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ffree(const Immediate& index) {
1133fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(index.value(), 7);
1134fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1135fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
1136fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC0 + index.value());
1137fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1138fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1139fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1140fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fsin() {
1141fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1142fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1143fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFE);
1144fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1145fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1146fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1147fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fcos() {
1148fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1149fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1150fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1151fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1152fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1153fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1154fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fptan() {
1155fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1156fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1157fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
1158fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1159fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
116024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fucompp() {
116124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
116224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDA);
116324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xE9);
116424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
116524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
116624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
116724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fprem() {
116824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
116924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xD9);
117024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xF8);
117124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
117224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
1173fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1174dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xchgl(CpuRegister dst, CpuRegister src) {
1175fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1176851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // There is a short version for rax.
1177851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't
1178851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // work.
1179851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool src_rax = src.AsRegister() == RAX;
1180851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool dst_rax = dst.AsRegister() == RAX;
1181851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  if (src_rax || dst_rax) {
1182851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOptionalRex32(src_rax ? dst : src);
1183851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits()));
1184851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    return;
1185851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1186851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1187851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // General case.
1188851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);
1189fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x87);
1190851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
1191fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1192fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1193ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1194ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffrayvoid X86_64Assembler::xchgq(CpuRegister dst, CpuRegister src) {
1195ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1196851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // There is a short version for rax.
1197851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't
1198851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // work.
1199851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool src_rax = src.AsRegister() == RAX;
1200851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool dst_rax = dst.AsRegister() == RAX;
1201851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  if (src_rax || dst_rax) {
1202851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // If src == target, emit a nop instead.
1203851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    if (src_rax && dst_rax) {
1204851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitUint8(0x90);
1205851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    } else {
1206851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitRex64(src_rax ? dst : src);
1207851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits()));
1208851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    }
1209851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    return;
1210851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1211851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1212851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // General case.
1213851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRex64(src, dst);
1214ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  EmitUint8(0x87);
1215851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
1216ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray}
1217ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1218ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1219dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xchgl(CpuRegister reg, const Address& address) {
1220fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1221dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1222fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x87);
1223dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1224fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1225fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1226fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
12273c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffrayvoid X86_64Assembler::cmpw(const Address& address, const Immediate& imm) {
12283c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12296ce017304099d1df97ffa016ce0efce79c67f344Nicolas Geoffray  CHECK(imm.is_int32());
123046fe0650be6a69f63b54c0967194350c6a145557Nicolas Geoffray  EmitOperandSizeOverride();
12313c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitOptionalRex32(address);
12323c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitComplex(7, address, imm);
12333c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray}
12343c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
12353c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
1236dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg, const Immediate& imm) {
1237fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12386ce017304099d1df97ffa016ce0efce79c67f344Nicolas Geoffray  CHECK(imm.is_int32());
1239dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1240fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(7, Operand(reg), imm);
1241fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1242fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1243fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1244dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg0, CpuRegister reg1) {
1245fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1246dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg0, reg1);
1247fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x3B);
1248dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg0.LowBits(), Operand(reg1));
1249fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1250fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1251fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1252dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg, const Address& address) {
1253fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1254dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1255fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x3B);
1256dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1257fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1258fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1259fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1260d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpl(const Address& address, CpuRegister reg) {
1261d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1262d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex32(reg, address);
1263d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x39);
1264d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOperand(reg.LowBits(), address);
1265d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1266d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1267d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1268d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpl(const Address& address, const Immediate& imm) {
1269d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12706ce017304099d1df97ffa016ce0efce79c67f344Nicolas Geoffray  CHECK(imm.is_int32());
1271d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex32(address);
1272d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitComplex(7, address, imm);
1273d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1274d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1275d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
12765a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::cmpq(CpuRegister reg0, CpuRegister reg1) {
12775a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12785a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(reg0, reg1);
12795a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x3B);
12805a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitOperand(reg0.LowBits(), Operand(reg1));
12815a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
12825a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
12835a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
128496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::cmpq(CpuRegister reg, const Immediate& imm) {
128596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
128696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  CHECK(imm.is_int32());  // cmpq only supports 32b immediate.
128796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(reg);
128896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitComplex(7, Operand(reg), imm);
128996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
129096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
129196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
129296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::cmpq(CpuRegister reg, const Address& address) {
129396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
129440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(reg, address);
129596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x3B);
129696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
129796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
129896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
129996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
1300d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpq(const Address& address, const Immediate& imm) {
1301d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  CHECK(imm.is_int32());  // cmpq only supports 32b immediate.
1302d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1303d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(address);
1304d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitComplex(7, address, imm);
1305d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1306d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1307d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1308dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister dst, CpuRegister src) {
1309fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1310dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1311fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x03);
1312dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
1313fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1314fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1315fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1316dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister reg, const Address& address) {
1317fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1318dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1319fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x03);
1320dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1321fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1322fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1323fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1324dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::testl(CpuRegister reg1, CpuRegister reg2) {
1325fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1326dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg1, reg2);
1327fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x85);
1328dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(reg1.LowBits(), reg2.LowBits());
1329fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1330fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1331fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1332cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravlevoid X86_64Assembler::testl(CpuRegister reg, const Address& address) {
1333cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1334cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitOptionalRex32(reg, address);
1335cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitUint8(0x85);
1336cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitOperand(reg.LowBits(), address);
1337cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle}
1338cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle
1339cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle
1340dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::testl(CpuRegister reg, const Immediate& immediate) {
1341fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1342fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // For registers that have a byte variant (RAX, RBX, RCX, and RDX)
1343dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // we only test the byte CpuRegister to keep the encoding short.
1344dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (immediate.is_uint8() && reg.AsRegister() < 4) {
1345fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use zero-extended 8-bit immediate.
1346dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    if (reg.AsRegister() == RAX) {
1347fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xA8);
1348fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1349fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xF6);
1350dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      EmitUint8(0xC0 + reg.AsRegister());
1351fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1352fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(immediate.value() & 0xFF);
1353dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  } else if (reg.AsRegister() == RAX) {
1354fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use short form if the destination is RAX.
1355fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xA9);
1356fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
1357fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1358dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitOptionalRex32(reg);
1359fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xF7);
1360fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(0, Operand(reg));
1361fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
1362fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1363fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1364fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1365fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1366d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::testq(CpuRegister reg1, CpuRegister reg2) {
1367d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1368d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(reg1, reg2);
1369d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x85);
1370d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRegisterOperand(reg1.LowBits(), reg2.LowBits());
1371d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1372d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1373d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1374f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffrayvoid X86_64Assembler::testq(CpuRegister reg, const Address& address) {
1375f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13767fd8b59ab9fcd896a95883ce7be781d74e849d60Mark Mendell  EmitRex64(reg, address);
1377f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitUint8(0x85);
1378f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
1379f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray}
1380f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1381f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1382dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::andl(CpuRegister dst, CpuRegister src) {
1383fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1384dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1385fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x23);
1386dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1387fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1389fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
13909574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::andl(CpuRegister reg, const Address& address) {
13919574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13929574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
13939574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x23);
13949574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
13959574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13969574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13979574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1398dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::andl(CpuRegister dst, const Immediate& imm) {
1399fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1400dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
1401fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(4, Operand(dst), imm);
1402fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1403fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1404fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1405412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffrayvoid X86_64Assembler::andq(CpuRegister reg, const Immediate& imm) {
1406412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1407412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  CHECK(imm.is_int32());  // andq only supports 32b immediate.
1408412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitRex64(reg);
1409412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitComplex(4, Operand(reg), imm);
1410412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray}
1411412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
1412412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
14139574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::andq(CpuRegister dst, CpuRegister src) {
14149574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14159574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitRex64(dst, src);
14169574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x23);
14179574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
14189574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14199574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14209574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
142140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::andq(CpuRegister dst, const Address& src) {
142240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
142340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(dst, src);
142440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x23);
142540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
142640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
142740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
142840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
1429dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::orl(CpuRegister dst, CpuRegister src) {
1430fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1431dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0B);
1433dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1436fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
14379574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::orl(CpuRegister reg, const Address& address) {
14389574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14399574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
14409574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x0B);
14419574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
14429574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14439574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14449574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1445dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::orl(CpuRegister dst, const Immediate& imm) {
1446fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1447dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
1448fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(1, Operand(dst), imm);
1449fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1450fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1451fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
14523f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendellvoid X86_64Assembler::orq(CpuRegister dst, const Immediate& imm) {
14533f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14543f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  CHECK(imm.is_int32());  // orq only supports 32b immediate.
14553f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitRex64(dst);
14563f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitComplex(1, Operand(dst), imm);
14573f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell}
14583f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
14593f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
14609574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::orq(CpuRegister dst, CpuRegister src) {
14619574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14629574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitRex64(dst, src);
14639574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x0B);
14649574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
14659574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14669574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14679574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
146840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::orq(CpuRegister dst, const Address& src) {
146940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
147040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(dst, src);
147140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x0B);
147240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
147340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
147440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
147540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
1476dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xorl(CpuRegister dst, CpuRegister src) {
1477fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1478dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1479fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x33);
1480dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1482fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
14835a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14849574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::xorl(CpuRegister reg, const Address& address) {
14859574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14869574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
14879574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x33);
14889574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
14899574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14909574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14919574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14929574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::xorl(CpuRegister dst, const Immediate& imm) {
14939574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14949574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(dst);
14959574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitComplex(6, Operand(dst), imm);
14969574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
14979574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
14989574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1499412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffrayvoid X86_64Assembler::xorq(CpuRegister dst, CpuRegister src) {
1500412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1501412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitRex64(dst, src);
1502412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitUint8(0x33);
1503412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
1504412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray}
1505412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
1506412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
15075a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::xorq(CpuRegister dst, const Immediate& imm) {
15085a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
15095a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // xorq only supports 32b immediate.
15105a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(dst);
15115a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitComplex(6, Operand(dst), imm);
15125a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
15135a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
151440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::xorq(CpuRegister dst, const Address& src) {
151540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
151640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitRex64(dst, src);
151740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(0x33);
151840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitOperand(dst.LowBits(), src);
151940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
152040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
152140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
1522dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#if 0
1523dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::rex(bool force, bool w, Register* r, Register* x, Register* b) {
1524fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // REX.WRXB
1525fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // W - 64-bit operand
1526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // R - MODRM.reg
1527fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // X - SIB.index
1528fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // B - MODRM.rm/SIB.base
1529dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = force ? 0x40 : 0;
1530dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
1531fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x48;  // REX.W000
1532fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1533dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (r != nullptr && *r >= Register::R8 && *r < Register::kNumberOfCpuRegisters) {
1534fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x44;  // REX.0R00
1535dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *r = static_cast<Register>(*r - 8);
1536fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1537dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (x != nullptr && *x >= Register::R8 && *x < Register::kNumberOfCpuRegisters) {
1538dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x42;  // REX.00X0
1539dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *x = static_cast<Register>(*x - 8);
1540dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1541dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (b != nullptr && *b >= Register::R8 && *b < Register::kNumberOfCpuRegisters) {
1542fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x41;  // REX.000B
1543dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *b = static_cast<Register>(*b - 8);
1544fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1545fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (rex != 0) {
1546fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(rex);
1547fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1548fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1549fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1550dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::rex_reg_mem(bool force, bool w, Register* dst, const Address& mem) {
1551dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // REX.WRXB
1552dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // W - 64-bit operand
1553dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // R - MODRM.reg
1554dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // X - SIB.index
1555dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // B - MODRM.rm/SIB.base
1556dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = mem->rex();
1557dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (force) {
1558dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x40;  // REX.0000
1559dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1560dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
1561dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x48;  // REX.W000
1562dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1563dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (dst != nullptr && *dst >= Register::R8 && *dst < Register::kNumberOfCpuRegisters) {
1564dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x44;  // REX.0R00
1565dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *dst = static_cast<Register>(*dst - 8);
1566dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1567dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (rex != 0) {
1568dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitUint8(rex);
1569dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1570dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
1571dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1572dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid rex_mem_reg(bool force, bool w, Address* mem, Register* src);
1573dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#endif
1574dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1575dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister reg, const Immediate& imm) {
1576fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1577dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1578fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, Operand(reg), imm);
1579fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1580fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1581fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1582dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addq(CpuRegister reg, const Immediate& imm) {
1583fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
15845a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // addq only supports 32b immediate.
1585dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(reg);
1586fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, Operand(reg), imm);
1587fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1588fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1589fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
159096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::addq(CpuRegister dst, const Address& address) {
159196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
15927fd8b59ab9fcd896a95883ce7be781d74e849d60Mark Mendell  EmitRex64(dst, address);
159396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x03);
159496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(dst.LowBits(), address);
159596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
159696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
159796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
15985a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::addq(CpuRegister dst, CpuRegister src) {
15995a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16005a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // 0x01 is addq r/m64 <- r/m64 + r64, with op1 in r/m and op2 in reg: so reverse EmitRex64
16015a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(src, dst);
16025a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x01);
16035a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
16045a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
16055a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
16065a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1607dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(const Address& address, CpuRegister reg) {
1608fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1609dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1610fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x01);
1611dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1612fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1613fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1614fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1615fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addl(const Address& address, const Immediate& imm) {
1616fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1617dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1618fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, address, imm);
1619fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1620fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1621fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1622dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister dst, CpuRegister src) {
1623fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1624dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2B);
1626dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1627fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1628fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1629fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1630dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister reg, const Immediate& imm) {
1631fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1632dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1633fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(5, Operand(reg), imm);
1634fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1635fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1636fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
16375a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::subq(CpuRegister reg, const Immediate& imm) {
16385a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16395a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // subq only supports 32b immediate.
16405a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(reg);
16415a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitComplex(5, Operand(reg), imm);
16425a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
16435a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
16445a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
16455a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::subq(CpuRegister dst, CpuRegister src) {
16465a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16475a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(dst, src);
16485a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x2B);
16495a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRegisterOperand(dst.LowBits(), src.LowBits());
16505a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
16515a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
16525a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
165396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::subq(CpuRegister reg, const Address& address) {
165496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16557fd8b59ab9fcd896a95883ce7be781d74e849d60Mark Mendell  EmitRex64(reg, address);
165696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x2B);
165796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(reg.LowBits() & 7, address);
165896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
165996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
166096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
1661dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister reg, const Address& address) {
1662fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1663dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1664fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2B);
1665dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1666fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1667fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1668fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1669fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cdq() {
1670fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1671fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x99);
1672fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1673fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1674fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1675d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cqo() {
1676d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1677d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64();
1678d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x99);
1679d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1680d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1681d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1682dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::idivl(CpuRegister reg) {
1683fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1684dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1685fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1686dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xF8 | reg.LowBits());
1687fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1688fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1689fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1690d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::idivq(CpuRegister reg) {
1691d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1692d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(reg);
1693d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0xF7);
1694d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0xF8 | reg.LowBits());
1695d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1696d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1697d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1698dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister dst, CpuRegister src) {
1699fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1700dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1701fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1702fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAF);
1703dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1704fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1705fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
17064a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendellvoid X86_64Assembler::imull(CpuRegister dst, CpuRegister src, const Immediate& imm) {
1707fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1708851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  CHECK(imm.is_int32());  // imull only supports 32b immediate.
1709851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
17104a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell  EmitOptionalRex32(dst, src);
1711851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1712851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // See whether imm can be represented as a sign-extended 8bit value.
1713851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  int32_t v32 = static_cast<int32_t>(imm.value());
1714ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  if (IsInt<8>(v32)) {
1715851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Sign-extension works.
1716851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x6B);
17174a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell    EmitOperand(dst.LowBits(), Operand(src));
1718851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(static_cast<uint8_t>(v32 & 0xFF));
1719851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
1720851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Not representable, use full immediate.
1721851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x69);
17224a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell    EmitOperand(dst.LowBits(), Operand(src));
1723851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitImmediate(imm);
1724851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1725fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1726fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1727fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
17284a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendellvoid X86_64Assembler::imull(CpuRegister reg, const Immediate& imm) {
17294a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell  imull(reg, reg, imm);
17304a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell}
17314a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell
17324a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell
1733dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg, const Address& address) {
1734fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1735dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1736fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1737fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAF);
1738dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1739fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1740fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1741fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
174234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister dst, CpuRegister src) {
174334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
174434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRex64(dst, src);
174534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0x0F);
174634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0xAF);
174734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRegisterOperand(dst.LowBits(), src.LowBits());
174834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
174934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
175034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
175134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister reg, const Immediate& imm) {
17523f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  imulq(reg, reg, imm);
17533f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell}
17543f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
17553f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendellvoid X86_64Assembler::imulq(CpuRegister dst, CpuRegister reg, const Immediate& imm) {
175634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
175734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  CHECK(imm.is_int32());  // imulq only supports 32b immediate.
1758851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
17593f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitRex64(dst, reg);
1760851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1761851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // See whether imm can be represented as a sign-extended 8bit value.
1762851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  int64_t v64 = imm.value();
1763ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  if (IsInt<8>(v64)) {
1764851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Sign-extension works.
1765851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x6B);
17663f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell    EmitOperand(dst.LowBits(), Operand(reg));
1767851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(static_cast<uint8_t>(v64 & 0xFF));
1768851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
1769851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Not representable, use full immediate.
1770851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x69);
17713f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell    EmitOperand(dst.LowBits(), Operand(reg));
1772851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitImmediate(imm);
1773851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
177434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
177534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
177634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister reg, const Address& address) {
177734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
177834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRex64(reg, address);
177934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0x0F);
178034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0xAF);
178134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitOperand(reg.LowBits(), address);
178234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
178334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
178434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
1785dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg) {
1786fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1787dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1788fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1789fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, Operand(reg));
1790fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1791fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1792fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
17930f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchezvoid X86_64Assembler::imulq(CpuRegister reg) {
17940f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
17950f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitRex64(reg);
17960f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitUint8(0xF7);
17970f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitOperand(5, Operand(reg));
17980f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez}
17990f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez
18000f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez
1801fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::imull(const Address& address) {
1802fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1803dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1804fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1805fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, address);
1806fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1807fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1808fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1809dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::mull(CpuRegister reg) {
1810fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1811dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1812fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1813fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, Operand(reg));
1814fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1815fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1816fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1817fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mull(const Address& address) {
1818fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1819dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1820fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1821fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, address);
1822fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1823fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1824fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1825dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shll(CpuRegister reg, const Immediate& imm) {
18261a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 4, reg, imm);
1827fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1828fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1829fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
18309aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shlq(CpuRegister reg, const Immediate& imm) {
18319aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 4, reg, imm);
18329aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18339aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18349aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
1835dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shll(CpuRegister operand, CpuRegister shifter) {
18369aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 4, operand, shifter);
18379aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18389aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18399aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18409aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shlq(CpuRegister operand, CpuRegister shifter) {
18419aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 4, operand, shifter);
1842fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1843fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1844fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1845dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shrl(CpuRegister reg, const Immediate& imm) {
18461a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 5, reg, imm);
18471a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray}
18481a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray
18491a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray
18501a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffrayvoid X86_64Assembler::shrq(CpuRegister reg, const Immediate& imm) {
18511a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(true, 5, reg, imm);
1852fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1854fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1855dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shrl(CpuRegister operand, CpuRegister shifter) {
18569aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 5, operand, shifter);
18579aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18589aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18599aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18609aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shrq(CpuRegister operand, CpuRegister shifter) {
18619aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 5, operand, shifter);
1862fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1863fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1864fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1865dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::sarl(CpuRegister reg, const Immediate& imm) {
18661a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 7, reg, imm);
1867fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1868fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1869fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1870dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::sarl(CpuRegister operand, CpuRegister shifter) {
18719aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 7, operand, shifter);
18729aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18739aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18749aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18759aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::sarq(CpuRegister reg, const Immediate& imm) {
18769aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 7, reg, imm);
18779aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
18789aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18799aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
18809aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::sarq(CpuRegister operand, CpuRegister shifter) {
18819aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 7, operand, shifter);
1882fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1883fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1884fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1885bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::roll(CpuRegister reg, const Immediate& imm) {
1886bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitGenericShift(false, 0, reg, imm);
1887bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
1888bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1889bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1890bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::roll(CpuRegister operand, CpuRegister shifter) {
1891bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitGenericShift(false, 0, operand, shifter);
1892bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
1893bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1894bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1895bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::rorl(CpuRegister reg, const Immediate& imm) {
1896bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitGenericShift(false, 1, reg, imm);
1897bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
1898bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1899bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1900bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::rorl(CpuRegister operand, CpuRegister shifter) {
1901bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitGenericShift(false, 1, operand, shifter);
1902bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
1903bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1904bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1905bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::rolq(CpuRegister reg, const Immediate& imm) {
1906bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitGenericShift(true, 0, reg, imm);
1907bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
1908bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1909bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1910bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::rolq(CpuRegister operand, CpuRegister shifter) {
1911bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitGenericShift(true, 0, operand, shifter);
1912bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
1913bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1914bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1915bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::rorq(CpuRegister reg, const Immediate& imm) {
1916bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitGenericShift(true, 1, reg, imm);
1917bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
1918bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1919bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1920bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::rorq(CpuRegister operand, CpuRegister shifter) {
1921bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitGenericShift(true, 1, operand, shifter);
1922bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
1923bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1924bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
1925dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::negl(CpuRegister reg) {
1926fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1927dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1928fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1929fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, Operand(reg));
1930fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1931fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1932705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
19332e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillainvoid X86_64Assembler::negq(CpuRegister reg) {
19342e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
19352e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitRex64(reg);
19362e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitUint8(0xF7);
19372e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitOperand(3, Operand(reg));
19382e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain}
19392e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain
1940fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1941dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::notl(CpuRegister reg) {
1942fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1943dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1944fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1945dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xD0 | reg.LowBits());
1946fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1947fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1948fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1949705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillainvoid X86_64Assembler::notq(CpuRegister reg) {
1950705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1951705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitRex64(reg);
1952705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitUint8(0xF7);
1953705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitOperand(2, Operand(reg));
1954705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain}
1955705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
1956705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
1957fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::enter(const Immediate& imm) {
1958fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1959fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC8);
1960ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  CHECK(imm.is_uint16()) << imm.value();
1961fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
1962fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8((imm.value() >> 8) & 0xFF);
1963fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x00);
1964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1966fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1967fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::leave() {
1968fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1969fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC9);
1970fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1971fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1972fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1973fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ret() {
1974fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1975fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC3);
1976fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1977fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1978fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1979fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ret(const Immediate& imm) {
1980fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1981fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC2);
1982fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_uint16());
1983fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
1984fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8((imm.value() >> 8) & 0xFF);
1985fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1986fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1987fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1988fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1989fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::nop() {
1990fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1991fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x90);
1992fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1993fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1994fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1995fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::int3() {
1996fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1997fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xCC);
1998fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1999fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2000fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2001fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::hlt() {
2002fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF4);
2004fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2005fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2006fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2007fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::j(Condition condition, Label* label) {
2008fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2009fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
2010fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kShortSize = 2;
2011fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kLongSize = 6;
2012fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
2013fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
2014ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe    if (IsInt<8>(offset - kShortSize)) {
2015fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x70 + condition);
2016fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8((offset - kShortSize) & 0xFF);
2017fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x0F);
2019fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x80 + condition);
2020fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitInt32(offset - kLongSize);
2021fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2022fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2023fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x0F);
2024fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x80 + condition);
2025fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
2026fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2027fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2028fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2029fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
203073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendellvoid X86_64Assembler::j(Condition condition, NearLabel* label) {
203173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
203273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  if (label->IsBound()) {
203373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    static const int kShortSize = 2;
203473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    int offset = label->Position() - buffer_.Size();
203573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    CHECK_LE(offset, 0);
203673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    CHECK(IsInt<8>(offset - kShortSize));
203773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8(0x70 + condition);
203873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8((offset - kShortSize) & 0xFF);
203973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  } else {
204073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8(0x70 + condition);
204173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitLabelLink(label);
204273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  }
204373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell}
204473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
204573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
204673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendellvoid X86_64Assembler::jrcxz(NearLabel* label) {
204773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
204873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  if (label->IsBound()) {
204973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    static const int kShortSize = 2;
205073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    int offset = label->Position() - buffer_.Size();
205173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    CHECK_LE(offset, 0);
205273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    CHECK(IsInt<8>(offset - kShortSize));
205373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8(0xE3);
205473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8((offset - kShortSize) & 0xFF);
205573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  } else {
205673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8(0xE3);
205773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitLabelLink(label);
205873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  }
205973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell}
206073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
206173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
2062dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::jmp(CpuRegister reg) {
2063fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2064dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
2065fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
2066dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(4, reg.LowBits());
2067fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2068fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2069fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::jmp(const Address& address) {
2070fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2071dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
2072fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
2073fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, address);
2074fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2075fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2076fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::jmp(Label* label) {
2077fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2078fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
2079fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kShortSize = 2;
2080fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kLongSize = 5;
2081fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
2082fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
2083ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe    if (IsInt<8>(offset - kShortSize)) {
2084fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xEB);
2085fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8((offset - kShortSize) & 0xFF);
2086fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2087fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xE9);
2088fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitInt32(offset - kLongSize);
2089fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2090fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2091fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xE9);
2092fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
2093fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2094fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2095fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2096fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
209773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendellvoid X86_64Assembler::jmp(NearLabel* label) {
209873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
209973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  if (label->IsBound()) {
210073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    static const int kShortSize = 2;
210173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    int offset = label->Position() - buffer_.Size();
210273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    CHECK_LE(offset, 0);
210373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    CHECK(IsInt<8>(offset - kShortSize));
210473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8(0xEB);
210573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8((offset - kShortSize) & 0xFF);
210673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  } else {
210773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8(0xEB);
210873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitLabelLink(label);
210973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  }
211073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell}
211173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
211273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
2113b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendellvoid X86_64Assembler::rep_movsw() {
2114b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2115b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell  EmitUint8(0x66);
2116b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell  EmitUint8(0xF3);
2117b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell  EmitUint8(0xA5);
2118b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell}
2119b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell
2120b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell
2121fca82208f7128fcda09b6a4743199308332558a2Dmitry PetrochenkoX86_64Assembler* X86_64Assembler::lock() {
2122fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2123fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF0);
2124fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return this;
2125fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2126fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2127fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2128dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpxchgl(const Address& address, CpuRegister reg) {
2129fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
213058d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitOptionalRex32(reg, address);
213158d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitUint8(0x0F);
213258d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitUint8(0xB1);
213358d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitOperand(reg.LowBits(), address);
213458d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell}
213558d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
213658d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
213758d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendellvoid X86_64Assembler::cmpxchgq(const Address& address, CpuRegister reg) {
213858d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
213958d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitRex64(reg, address);
2140fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
2141fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB1);
2142dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
2143fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2144fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
214558d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
2146fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mfence() {
2147fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2148fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
2149fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAE);
2150fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF0);
2151fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2152fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
21535a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
2154fca82208f7128fcda09b6a4743199308332558a2Dmitry PetrochenkoX86_64Assembler* X86_64Assembler::gs() {
21555a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // TODO: gs is a prefix and not an instruction
2156fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2157fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x65);
2158fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return this;
2159fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2160fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
21615a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
2162dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::AddImmediate(CpuRegister reg, const Immediate& imm) {
2163fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int value = imm.value();
2164dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (value != 0) {
2165dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    if (value > 0) {
2166fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      addl(reg, imm);
2167dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    } else {
2168fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      subl(reg, Immediate(value));
2169fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2170fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2171fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2172fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2173fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
21745a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::setcc(Condition condition, CpuRegister dst) {
21755a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
21765a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // RSP, RBP, RDI, RSI need rex prefix (else the pattern encodes ah/bh/ch/dh).
21775a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (dst.NeedsRex() || dst.AsRegister() > 3) {
21785a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitOptionalRex(true, false, false, false, dst.NeedsRex());
21795a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
21805a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x0F);
21815a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x90 + condition);
21825a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0xC0 + dst.LowBits());
21835a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
21845a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
218571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::bswapl(CpuRegister dst) {
218671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
218771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, false, false, false, dst.NeedsRex());
218871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
218971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0xC8 + dst.LowBits());
219071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
219171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
219271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::bswapq(CpuRegister dst) {
219371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
219471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, true, false, false, dst.NeedsRex());
219571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
219671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0xC8 + dst.LowBits());
219771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
219871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
2199bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::bsfl(CpuRegister dst, CpuRegister src) {
2200bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2201bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitOptionalRex32(dst, src);
2202bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitUint8(0x0F);
2203bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitUint8(0xBC);
2204bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitRegisterOperand(dst.LowBits(), src.LowBits());
2205bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
2206bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
2207bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::bsfl(CpuRegister dst, const Address& src) {
2208bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2209bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitOptionalRex32(dst, src);
2210bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitUint8(0x0F);
2211bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitUint8(0xBC);
2212bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitOperand(dst.LowBits(), src);
2213bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
2214bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
2215bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::bsfq(CpuRegister dst, CpuRegister src) {
2216bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2217bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitRex64(dst, src);
2218bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitUint8(0x0F);
2219bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitUint8(0xBC);
2220bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitRegisterOperand(dst.LowBits(), src.LowBits());
2221bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
2222bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
2223bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendellvoid X86_64Assembler::bsfq(CpuRegister dst, const Address& src) {
2224bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2225bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitRex64(dst, src);
2226bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitUint8(0x0F);
2227bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitUint8(0xBC);
2228bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell  EmitOperand(dst.LowBits(), src);
2229bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell}
2230bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell
22318ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendellvoid X86_64Assembler::bsrl(CpuRegister dst, CpuRegister src) {
22328ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22338ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitOptionalRex32(dst, src);
22348ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0x0F);
22358ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0xBD);
22368ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitRegisterOperand(dst.LowBits(), src.LowBits());
22378ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell}
22388ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell
22398ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendellvoid X86_64Assembler::bsrl(CpuRegister dst, const Address& src) {
22408ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22418ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitOptionalRex32(dst, src);
22428ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0x0F);
22438ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0xBD);
22448ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitOperand(dst.LowBits(), src);
22458ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell}
22468ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell
22478ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendellvoid X86_64Assembler::bsrq(CpuRegister dst, CpuRegister src) {
22488ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22498ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitRex64(dst, src);
22508ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0x0F);
22518ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0xBD);
22528ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitRegisterOperand(dst.LowBits(), src.LowBits());
22538ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell}
22548ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell
22558ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendellvoid X86_64Assembler::bsrq(CpuRegister dst, const Address& src) {
22568ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22578ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitRex64(dst, src);
22588ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0x0F);
22598ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitUint8(0xBD);
22608ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell  EmitOperand(dst.LowBits(), src);
22618ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell}
22625a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
22633f67e692860d281858485d48a4f1f81b907f1444Aart Bikvoid X86_64Assembler::popcntl(CpuRegister dst, CpuRegister src) {
22643f67e692860d281858485d48a4f1f81b907f1444Aart Bik  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22653f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0xF3);
22663f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitOptionalRex32(dst, src);
22673f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0x0F);
22683f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0xB8);
22693f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitRegisterOperand(dst.LowBits(), src.LowBits());
22703f67e692860d281858485d48a4f1f81b907f1444Aart Bik}
22713f67e692860d281858485d48a4f1f81b907f1444Aart Bik
22723f67e692860d281858485d48a4f1f81b907f1444Aart Bikvoid X86_64Assembler::popcntl(CpuRegister dst, const Address& src) {
22733f67e692860d281858485d48a4f1f81b907f1444Aart Bik  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22743f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0xF3);
22753f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitOptionalRex32(dst, src);
22763f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0x0F);
22773f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0xB8);
22783f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitOperand(dst.LowBits(), src);
22793f67e692860d281858485d48a4f1f81b907f1444Aart Bik}
22803f67e692860d281858485d48a4f1f81b907f1444Aart Bik
22813f67e692860d281858485d48a4f1f81b907f1444Aart Bikvoid X86_64Assembler::popcntq(CpuRegister dst, CpuRegister src) {
22823f67e692860d281858485d48a4f1f81b907f1444Aart Bik  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22833f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0xF3);
22843f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitRex64(dst, src);
22853f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0x0F);
22863f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0xB8);
22873f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitRegisterOperand(dst.LowBits(), src.LowBits());
22883f67e692860d281858485d48a4f1f81b907f1444Aart Bik}
22893f67e692860d281858485d48a4f1f81b907f1444Aart Bik
22903f67e692860d281858485d48a4f1f81b907f1444Aart Bikvoid X86_64Assembler::popcntq(CpuRegister dst, const Address& src) {
22913f67e692860d281858485d48a4f1f81b907f1444Aart Bik  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
22923f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0xF3);
22933f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitRex64(dst, src);
22943f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0x0F);
22953f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitUint8(0xB8);
22963f67e692860d281858485d48a4f1f81b907f1444Aart Bik  EmitOperand(dst.LowBits(), src);
22973f67e692860d281858485d48a4f1f81b907f1444Aart Bik}
22983f67e692860d281858485d48a4f1f81b907f1444Aart Bik
229921030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampevoid X86_64Assembler::repne_scasw() {
230021030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
230121030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe  EmitUint8(0x66);
230221030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe  EmitUint8(0xF2);
230321030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe  EmitUint8(0xAF);
230421030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe}
230521030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe
230621030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe
230771311f868e2579fa5d40b24e620198734119d1a0agicsakivoid X86_64Assembler::repe_cmpsw() {
230871311f868e2579fa5d40b24e620198734119d1a0agicsaki  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
230971311f868e2579fa5d40b24e620198734119d1a0agicsaki  EmitUint8(0x66);
231071311f868e2579fa5d40b24e620198734119d1a0agicsaki  EmitUint8(0xF3);
231171311f868e2579fa5d40b24e620198734119d1a0agicsaki  EmitUint8(0xA7);
231271311f868e2579fa5d40b24e620198734119d1a0agicsaki}
231371311f868e2579fa5d40b24e620198734119d1a0agicsaki
231471311f868e2579fa5d40b24e620198734119d1a0agicsaki
2315970abfb65530b700f3a0cc8b90b131df5420cec3agicsakivoid X86_64Assembler::repe_cmpsl() {
2316970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2317970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki  EmitUint8(0xF3);
2318970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki  EmitUint8(0xA7);
2319970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki}
2320970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki
2321970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki
23223fd0e6a86430bf060c7eb391c1378394c4a2c574agicsakivoid X86_64Assembler::repe_cmpsq() {
23233fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
23243fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki  EmitUint8(0xF3);
23253fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki  EmitRex64();
23263fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki  EmitUint8(0xA7);
23273fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki}
23283fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki
23293fd0e6a86430bf060c7eb391c1378394c4a2c574agicsaki
2330fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
2331fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: Need to have a code constants table.
2332fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int64_t constant = bit_cast<int64_t, double>(value);
2333fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Immediate(High32Bits(constant)));
2334fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Immediate(Low32Bits(constant)));
2335dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movsd(dst, Address(CpuRegister(RSP), 0));
233613735955f39b3b304c37d2b2840663c131262c18Ian Rogers  addq(CpuRegister(RSP), Immediate(2 * sizeof(intptr_t)));
2337fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2338fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2339fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2340fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Align(int alignment, int offset) {
2341fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(IsPowerOfTwo(alignment));
2342fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit nop instruction until the real position is aligned.
2343fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) {
2344fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    nop();
2345fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2346fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2347fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2348fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2349fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Bind(Label* label) {
2350fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int bound = buffer_.Size();
2351fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(!label->IsBound());  // Labels can only be bound once.
2352fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  while (label->IsLinked()) {
2353fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int position = label->LinkPosition();
2354fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int next = buffer_.Load<int32_t>(position);
2355fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    buffer_.Store<int32_t>(position, bound - (position + 4));
2356fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    label->position_ = next;
2357fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2358fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  label->BindTo(bound);
2359fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2360fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2361fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
236273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendellvoid X86_64Assembler::Bind(NearLabel* label) {
236373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  int bound = buffer_.Size();
236473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  CHECK(!label->IsBound());  // Labels can only be bound once.
236573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  while (label->IsLinked()) {
236673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    int position = label->LinkPosition();
236773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    uint8_t delta = buffer_.Load<uint8_t>(position);
236873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    int offset = bound - (position + 1);
236973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    CHECK(IsInt<8>(offset));
237073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    buffer_.Store<int8_t>(position, offset);
237173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    label->position_ = delta != 0u ? label->position_ - delta : 0;
237273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  }
237373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  label->BindTo(bound);
237473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell}
237573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
237673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
2377dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOperand(uint8_t reg_or_opcode, const Operand& operand) {
2378fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GE(reg_or_opcode, 0);
2379fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(reg_or_opcode, 8);
2380fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  const int length = operand.length_;
2381fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GT(length, 0);
2382fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit the ModRM byte updated with the given reg value.
2383fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(operand.encoding_[0] & 0x38, 0);
2384fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(operand.encoding_[0] + (reg_or_opcode << 3));
2385fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit the rest of the encoded operand.
2386fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (int i = 1; i < length; i++) {
2387fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(operand.encoding_[i]);
2388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2389f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  AssemblerFixup* fixup = operand.GetFixup();
2390f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  if (fixup != nullptr) {
2391f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    EmitFixup(fixup);
2392f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2393fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2394fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2395fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2396fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitImmediate(const Immediate& imm) {
23975a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (imm.is_int32()) {
23985a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt32(static_cast<int32_t>(imm.value()));
23995a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  } else {
24005a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt64(imm.value());
24015a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
2402fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2403fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2404fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2405dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitComplex(uint8_t reg_or_opcode,
2406dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                  const Operand& operand,
2407dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                  const Immediate& immediate) {
2408fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GE(reg_or_opcode, 0);
2409fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(reg_or_opcode, 8);
2410fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (immediate.is_int8()) {
2411fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use sign-extended 8-bit immediate.
2412fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x83);
2413fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, operand);
2414fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(immediate.value() & 0xFF);
2415dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  } else if (operand.IsRegister(CpuRegister(RAX))) {
2416fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use short form if the destination is eax.
2417fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x05 + (reg_or_opcode << 3));
2418fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
2419fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2420fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x81);
2421fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, operand);
2422fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
2423fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2424fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2425fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2426fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2427fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitLabel(Label* label, int instruction_size) {
2428fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
2429fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
2430fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
2431fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitInt32(offset - instruction_size);
2432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2433fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
2434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2436fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2437fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2438fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitLabelLink(Label* label) {
2439fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(!label->IsBound());
2440fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int position = buffer_.Size();
2441fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitInt32(label->position_);
2442fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  label->LinkTo(position);
2443fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2444fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2445fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
244673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendellvoid X86_64Assembler::EmitLabelLink(NearLabel* label) {
244773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  CHECK(!label->IsBound());
244873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  int position = buffer_.Size();
244973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  if (label->IsLinked()) {
245073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    // Save the delta in the byte that we have to play with.
245173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    uint32_t delta = position - label->LinkPosition();
245273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    CHECK(IsUint<8>(delta));
245373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8(delta & 0xFF);
245473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  } else {
245573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell    EmitUint8(0);
245673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  }
245773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell  label->LinkTo(position);
245873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell}
245973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
246073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell
24611a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffrayvoid X86_64Assembler::EmitGenericShift(bool wide,
24621a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       int reg_or_opcode,
24631a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister reg,
24641a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       const Immediate& imm) {
2465fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_int8());
24671a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  if (wide) {
24681a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray    EmitRex64(reg);
2469851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
2470851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOptionalRex32(reg);
24711a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  }
2472fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (imm.value() == 1) {
2473fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xD1);
2474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, Operand(reg));
2475fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2476fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xC1);
2477fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, Operand(reg));
2478fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(imm.value() & 0xFF);
2479fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2480fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2482fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
24839aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::EmitGenericShift(bool wide,
24849aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle                                       int reg_or_opcode,
24851a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister operand,
24861a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister shifter) {
2487fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2488dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CHECK_EQ(shifter.AsRegister(), RCX);
24899aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  if (wide) {
24909aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle    EmitRex64(operand);
24919aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  } else {
24929aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle    EmitOptionalRex32(operand);
24939aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  }
2494fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD3);
2495fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(reg_or_opcode, Operand(operand));
2496fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2497fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2498dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) {
2499dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // REX.WRXB
2500dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // W - 64-bit operand
2501dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // R - MODRM.reg
2502dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // X - SIB.index
2503dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // B - MODRM.rm/SIB.base
2504dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = force ? 0x40 : 0;
2505dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
2506dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x48;  // REX.W000
2507dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2508dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (r) {
2509dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x44;  // REX.0R00
2510dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2511dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (x) {
2512dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x42;  // REX.00X0
2513dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2514dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (b) {
2515dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x41;  // REX.000B
2516dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2517dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (rex != 0) {
2518dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitUint8(rex);
2519dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2520dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2521dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2522dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister reg) {
2523fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov  EmitOptionalRex(false, false, false, false, reg.NeedsRex());
2524dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2525dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2526dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, CpuRegister src) {
2527dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2528dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2529dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2530dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, XmmRegister src) {
2531dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2532dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2533dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2534dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, XmmRegister src) {
2535dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2536dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2537dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2538dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, CpuRegister src) {
2539dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2540dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2541dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2542dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(const Operand& operand) {
2543790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2544790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2545790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2546790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2547dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2548dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2549dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, const Operand& operand) {
2550790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2551790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2552790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2553790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2554790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2555790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2556790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2557dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2558dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2559dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, const Operand& operand) {
2560790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2561790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2562790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2563790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2564790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2565790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2566790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2567dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2568dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2569d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::EmitRex64() {
2570d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex(false, true, false, false, false);
2571d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
2572d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
2573dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister reg) {
2574fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov  EmitOptionalRex(false, true, false, false, reg.NeedsRex());
2575dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2576fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov
2577d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::EmitRex64(const Operand& operand) {
2578d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  uint8_t rex = operand.rex();
2579d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  rex |= 0x48;  // REX.W000
2580d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(rex);
2581d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
2582d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
2583dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister dst, CpuRegister src) {
2584dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2585dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2586dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2587102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffrayvoid X86_64Assembler::EmitRex64(XmmRegister dst, CpuRegister src) {
2588102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2589102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray}
2590102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray
2591624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainvoid X86_64Assembler::EmitRex64(CpuRegister dst, XmmRegister src) {
2592624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2593624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain}
2594624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
2595dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister dst, const Operand& operand) {
2596790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = 0x48 | operand.rex();  // REX.W000
2597790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2598790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2599790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
260040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(rex);
260140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell}
260240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell
260340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendellvoid X86_64Assembler::EmitRex64(XmmRegister dst, const Operand& operand) {
260440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  uint8_t rex = 0x48 | operand.rex();  // REX.W000
260540741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  if (dst.NeedsRex()) {
260640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell    rex |= 0x44;  // REX.0R00
2607790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
260840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell  EmitUint8(rex);
2609dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2610dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2611dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, CpuRegister src) {
2612d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // For src, SPL, BPL, SIL, DIL need the rex prefix.
2613d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  bool force = src.AsRegister() > 3;
2614d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex(force, false, dst.NeedsRex(), false, src.NeedsRex());
2615dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2616dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2617dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, const Operand& operand) {
2618d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  uint8_t rex = operand.rex();
2619d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // For dst, SPL, BPL, SIL, DIL need the rex prefix.
2620d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  bool force = dst.AsRegister() > 3;
2621d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  if (force) {
2622d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu    rex |= 0x40;  // REX.0000
2623d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  }
2624790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2625790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2626790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2627790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2628790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2629790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2630dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2631dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2632dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckystatic dwarf::Reg DWARFReg(Register reg) {
2633dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  return dwarf::Reg::X86_64Core(static_cast<int>(reg));
2634dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}
2635dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckystatic dwarf::Reg DWARFReg(FloatRegister reg) {
2636dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  return dwarf::Reg::X86_64Fp(static_cast<int>(reg));
2637dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}
2638dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
2639790a6b7312979513710c366b411ba6791ddf78c2Ian Rogersconstexpr size_t kFramePointerSize = 8;
2640790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers
2641fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
2642790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                                 const std::vector<ManagedRegister>& spill_regs,
2643790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                                 const ManagedRegisterEntrySpills& entry_spills) {
26448c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky  DCHECK_EQ(buffer_.Size(), 0U);  // Nothing emitted yet.
2645dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.SetCurrentCFAOffset(8);  // Return address on stack.
2646fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(frame_size, kStackAlignment);
2647c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int gpr_count = 0;
2648fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (int i = spill_regs.size() - 1; i >= 0; --i) {
2649c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2650c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsCpuRegister()) {
2651c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      pushq(spill.AsCpuRegister());
2652c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      gpr_count++;
2653dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.AdjustCFAOffset(kFramePointerSize);
2654dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.RelOffset(DWARFReg(spill.AsCpuRegister().AsRegister()), 0);
2655c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2656fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
26578c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky  // return address then method on stack.
2658c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t rest_of_frame = static_cast<int64_t>(frame_size)
2659c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov                          - (gpr_count * kFramePointerSize)
2660c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov                          - kFramePointerSize /*return address*/;
2661c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  subq(CpuRegister(RSP), Immediate(rest_of_frame));
2662dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(rest_of_frame);
2663547cdfd21ee21e4ab9ca8692d6ef47c62ee7ea52Tong Shen
2664c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  // spill xmms
2665c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t offset = rest_of_frame;
2666c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  for (int i = spill_regs.size() - 1; i >= 0; --i) {
2667c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2668c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsXmmRegister()) {
2669c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      offset -= sizeof(double);
2670c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      movsd(Address(CpuRegister(RSP), offset), spill.AsXmmRegister());
2671dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.RelOffset(DWARFReg(spill.AsXmmRegister().AsFloatRegister()), offset);
2672c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2673c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  }
2674cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe
2675e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK_EQ(kX86_64PointerSize, kFramePointerSize);
2676c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov
2677e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  movq(Address(CpuRegister(RSP), 0), method_reg.AsX86_64().AsCpuRegister());
2678fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2679fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (size_t i = 0; i < entry_spills.size(); ++i) {
2680fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    ManagedRegisterSpill spill = entry_spills.at(i);
2681fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (spill.AsX86_64().IsCpuRegister()) {
2682fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (spill.getSize() == 8) {
2683dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movq(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()),
2684dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers             spill.AsX86_64().AsCpuRegister());
2685fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2686fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(spill.getSize(), 4);
2687dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movl(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsCpuRegister());
2688fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2689fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2690fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (spill.getSize() == 8) {
2691dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movsd(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister());
2692fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2693fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(spill.getSize(), 4);
2694dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movss(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister());
2695fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2696fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2697fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2698fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2699fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2700fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::RemoveFrame(size_t frame_size,
2701fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                            const std::vector<ManagedRegister>& spill_regs) {
2702fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(frame_size, kStackAlignment);
2703dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.RememberState();
2704c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int gpr_count = 0;
2705c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  // unspill xmms
2706c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t offset = static_cast<int64_t>(frame_size) - (spill_regs.size() * kFramePointerSize) - 2 * kFramePointerSize;
2707fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (size_t i = 0; i < spill_regs.size(); ++i) {
2708c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2709c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsXmmRegister()) {
2710c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      offset += sizeof(double);
2711c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      movsd(spill.AsXmmRegister(), Address(CpuRegister(RSP), offset));
2712dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.Restore(DWARFReg(spill.AsXmmRegister().AsFloatRegister()));
2713c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    } else {
2714c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      gpr_count++;
2715c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2716c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  }
2717dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  int adjust = static_cast<int>(frame_size) - (gpr_count * kFramePointerSize) - kFramePointerSize;
2718dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  addq(CpuRegister(RSP), Immediate(adjust));
2719dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(-adjust);
2720c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  for (size_t i = 0; i < spill_regs.size(); ++i) {
2721c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2722c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsCpuRegister()) {
2723c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      popq(spill.AsCpuRegister());
2724dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.AdjustCFAOffset(-static_cast<int>(kFramePointerSize));
2725dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.Restore(DWARFReg(spill.AsCpuRegister().AsRegister()));
2726c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2727fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2728fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  ret();
2729dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  // The CFI should be restored for any code that follows the exit block.
2730dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.RestoreState();
2731dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.DefCFAOffset(frame_size);
2732fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2733fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2734fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::IncreaseFrameSize(size_t adjust) {
2735fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(adjust, kStackAlignment);
27365408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate  addq(CpuRegister(RSP), Immediate(-static_cast<int64_t>(adjust)));
2737dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(adjust);
2738fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2739fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2740fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::DecreaseFrameSize(size_t adjust) {
2741fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(adjust, kStackAlignment);
2742dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  addq(CpuRegister(RSP), Immediate(adjust));
2743dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(-adjust);
2744fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2745fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2746fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) {
2747fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2748fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (src.IsNoRegister()) {
2749fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2750fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsCpuRegister()) {
2751fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2752fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(4u, size);
2753dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movl(Address(CpuRegister(RSP), offs), src.AsCpuRegister());
2754fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2755fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(8u, size);
2756dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movq(Address(CpuRegister(RSP), offs), src.AsCpuRegister());
2757fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2758fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsRegisterPair()) {
2759fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2760dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(Address(CpuRegister(RSP), offs), src.AsRegisterPairLow());
2761dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(Address(CpuRegister(RSP), FrameOffset(offs.Int32Value()+4)),
2762fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko         src.AsRegisterPairHigh());
2763fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsX87Register()) {
2764fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2765dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fstps(Address(CpuRegister(RSP), offs));
2766fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2767dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fstpl(Address(CpuRegister(RSP), offs));
2768fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2769fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2770fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(src.IsXmmRegister());
2771fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2772dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movss(Address(CpuRegister(RSP), offs), src.AsXmmRegister());
2773fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2774dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movsd(Address(CpuRegister(RSP), offs), src.AsXmmRegister());
2775fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2776fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2777fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2778fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2779fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
2780fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2781fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(src.IsCpuRegister());
2782cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  movl(Address(CpuRegister(RSP), dest), src.AsCpuRegister());
2783fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2784fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2785fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
2786fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2787fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(src.IsCpuRegister());
2788dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), dest), src.AsCpuRegister());
2789fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2790fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2791fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
2792dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                            ManagedRegister) {
2793dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(Address(CpuRegister(RSP), dest), Immediate(imm));  // TODO(64) movq?
2794fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2795fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2796dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
2797dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                               ManagedRegister) {
2798fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movl(Address::Absolute(dest, true), Immediate(imm));  // TODO(64) movq?
2799fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2800fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2801dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreStackOffsetToThread64(ThreadOffset<8> thr_offs,
2802dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                 FrameOffset fr_offs,
2803dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                 ManagedRegister mscratch) {
2804fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2805fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2806dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), fr_offs));
2807fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister());
2808fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2809fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2810dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreStackPointerToThread64(ThreadOffset<8> thr_offs) {
2811dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(Address::Absolute(thr_offs, true), CpuRegister(RSP));
2812fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2813fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2814fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreSpanning(FrameOffset /*dst*/, ManagedRegister /*src*/,
2815fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                 FrameOffset /*in_off*/, ManagedRegister /*scratch*/) {
2816fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  UNIMPLEMENTED(FATAL);  // this case only currently exists for ARM
2817fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2818fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2819fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) {
2820fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2821fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (dest.IsNoRegister()) {
2822fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2823fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsCpuRegister()) {
2824fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2825fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(4u, size);
2826dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movl(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2827fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2828fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(8u, size);
2829dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2830fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2831fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsRegisterPair()) {
2832fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2833dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(dest.AsRegisterPairLow(), Address(CpuRegister(RSP), src));
2834dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(dest.AsRegisterPairHigh(), Address(CpuRegister(RSP), FrameOffset(src.Int32Value()+4)));
2835fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsX87Register()) {
2836fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2837dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      flds(Address(CpuRegister(RSP), src));
2838fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2839dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fldl(Address(CpuRegister(RSP), src));
2840fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2841fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2842fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(dest.IsXmmRegister());
2843fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2844dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), src));
2845fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2846dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), src));
2847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2849fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2850fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2851dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) {
2852fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (dest.IsNoRegister()) {
2854fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2855fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsCpuRegister()) {
2856fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(4u, size);
2857dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    gs()->movl(dest.AsCpuRegister(), Address::Absolute(src, true));
2858fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsRegisterPair()) {
2859fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(8u, size);
2860fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    gs()->movq(dest.AsRegisterPairLow(), Address::Absolute(src, true));
2861fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsX87Register()) {
2862fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2863fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->flds(Address::Absolute(src, true));
2864fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2865fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->fldl(Address::Absolute(src, true));
2866fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2867fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2868fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(dest.IsXmmRegister());
2869fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2870fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->movss(dest.AsXmmRegister(), Address::Absolute(src, true));
2871fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2872fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->movsd(dest.AsXmmRegister(), Address::Absolute(src, true));
2873fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2874fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2875fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2876fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2877e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid X86_64Assembler::LoadRef(ManagedRegister mdest, FrameOffset src) {
2878fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2879fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister());
2880dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2881fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2882fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2883e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid X86_64Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs,
28844d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain                              bool unpoison_reference) {
2885fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2886fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
2887f889267adadd62c92d1d3726764598946a961c10Hiroshi Yamauchi  movl(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
28884d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain  if (unpoison_reference) {
28894d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain    MaybeUnpoisonHeapReference(dest.AsCpuRegister());
2890b88f0b16dbaff09a140d2a62b66eca2736ff514bHiroshi Yamauchi  }
2891fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2892fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2893fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
2894fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                              Offset offs) {
2895fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2896fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
2897fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
2898fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2899fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2900dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) {
2901fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2902fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister());
2903fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(dest.AsCpuRegister(), Address::Absolute(offs, true));
2904fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2905fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2906fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::SignExtend(ManagedRegister mreg, size_t size) {
2907fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister reg = mreg.AsX86_64();
2908fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(size == 1 || size == 2) << size;
2909fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(reg.IsCpuRegister()) << reg;
2910fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (size == 1) {
2911dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movsxb(reg.AsCpuRegister(), reg.AsCpuRegister());
2912fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2913fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    movsxw(reg.AsCpuRegister(), reg.AsCpuRegister());
2914fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2915fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2916fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2917fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ZeroExtend(ManagedRegister mreg, size_t size) {
2918fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister reg = mreg.AsX86_64();
2919fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(size == 1 || size == 2) << size;
2920fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(reg.IsCpuRegister()) << reg;
2921fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (size == 1) {
2922dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movzxb(reg.AsCpuRegister(), reg.AsCpuRegister());
2923fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2924fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    movzxw(reg.AsCpuRegister(), reg.AsCpuRegister());
2925fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2926fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2927fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2928fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
2929fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2930fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2931fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (!dest.Equals(src)) {
2932fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (dest.IsCpuRegister() && src.IsCpuRegister()) {
2933fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      movq(dest.AsCpuRegister(), src.AsCpuRegister());
2934fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else if (src.IsX87Register() && dest.IsXmmRegister()) {
2935fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      // Pass via stack and pop X87 register
2936dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      subl(CpuRegister(RSP), Immediate(16));
2937fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (size == 4) {
2938fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(src.AsX87Register(), ST0);
2939dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        fstps(Address(CpuRegister(RSP), 0));
2940dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0));
2941fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2942fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(src.AsX87Register(), ST0);
2943dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        fstpl(Address(CpuRegister(RSP), 0));
2944dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0));
2945fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2946dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      addq(CpuRegister(RSP), Immediate(16));
2947fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2948fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      // TODO: x87, SSE
2949fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      UNIMPLEMENTED(FATAL) << ": Move " << dest << ", " << src;
2950fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2951fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2952fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2953fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2954e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid X86_64Assembler::CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) {
2955fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2956fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2957dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), src));
2958dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(Address(CpuRegister(RSP), dest), scratch.AsCpuRegister());
2959fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2960fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2961dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CopyRawPtrFromThread64(FrameOffset fr_offs,
2962dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                             ThreadOffset<8> thr_offs,
2963dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                             ManagedRegister mscratch) {
2964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2966fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(scratch.AsCpuRegister(), Address::Absolute(thr_offs, true));
2967fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Store(fr_offs, scratch, 8);
2968fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2969fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2970dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CopyRawPtrToThread64(ThreadOffset<8> thr_offs,
2971dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                           FrameOffset fr_offs,
2972dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                           ManagedRegister mscratch) {
2973fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2974fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2975fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Load(scratch, fr_offs, 8);
2976fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister());
2977fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2978fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2979e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid X86_64Assembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch,
2980e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           size_t size) {
2981fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2982fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (scratch.IsCpuRegister() && size == 8) {
2983fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, src, 4);
2984fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(dest, scratch, 4);
2985fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, FrameOffset(src.Int32Value() + 4), 4);
2986fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(FrameOffset(dest.Int32Value() + 4), scratch, 4);
2987fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2988fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, src, size);
2989fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(dest, scratch, size);
2990fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2991fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2992fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2993fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset /*dst*/, ManagedRegister /*src_base*/, Offset /*src_offset*/,
2994fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister /*scratch*/, size_t /*size*/) {
2995fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  UNIMPLEMENTED(FATAL);
2996fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2997fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2998fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
2999fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister scratch, size_t size) {
3000fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsNoRegister());
3001fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
3002dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  pushq(Address(CpuRegister(RSP), src));
3003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(dest_base.AsX86_64().AsCpuRegister(), dest_offset));
3004fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3005fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3006fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
3007fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch, size_t size) {
3008dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
3009fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
3010dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(scratch, Address(CpuRegister(RSP), src_base));
3011fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(scratch, Address(scratch, src_offset));
3012dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), dest), scratch);
3013fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3014fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3015fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(ManagedRegister dest, Offset dest_offset,
3016fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister src, Offset src_offset,
3017fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister scratch, size_t size) {
3018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
3019fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsNoRegister());
3020fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Address(src.AsX86_64().AsCpuRegister(), src_offset));
3021fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(dest.AsX86_64().AsCpuRegister(), dest_offset));
3022fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3023fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3024fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
3025fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch, size_t size) {
3026dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
3027fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
3028fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(dest.Int32Value(), src.Int32Value());
3029dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(scratch, Address(CpuRegister(RSP), src));
3030fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Address(scratch, src_offset));
3031fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(scratch, dest_offset));
3032fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3033fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3034fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::MemoryBarrier(ManagedRegister) {
3035fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  mfence();
3036fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3037fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3038eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::CreateHandleScopeEntry(ManagedRegister mout_reg,
3039eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                   FrameOffset handle_scope_offset,
3040fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   ManagedRegister min_reg, bool null_allowed) {
3041fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister out_reg = mout_reg.AsX86_64();
3042fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister in_reg = min_reg.AsX86_64();
3043fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (in_reg.IsNoRegister()) {  // TODO(64): && null_allowed
30442cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    // Use out_reg as indicator of null.
3045fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    in_reg = out_reg;
3046fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // TODO: movzwl
3047eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    movl(in_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
3048fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
3049fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(in_reg.IsCpuRegister());
3050fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(out_reg.IsCpuRegister());
3051fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  VerifyObject(in_reg, null_allowed);
3052fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (null_allowed) {
3053fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Label null_arg;
3054fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (!out_reg.Equals(in_reg)) {
3055fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
3056fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
3057fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
3058fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    j(kZero, &null_arg);
3059eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
3060fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Bind(&null_arg);
3061fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
3062eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
3063fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
3064fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3065fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3066eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::CreateHandleScopeEntry(FrameOffset out_off,
3067eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                   FrameOffset handle_scope_offset,
3068fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   ManagedRegister mscratch,
3069fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   bool null_allowed) {
3070fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
3071fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
3072fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (null_allowed) {
3073fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Label null_arg;
3074eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
3075fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    testl(scratch.AsCpuRegister(), scratch.AsCpuRegister());
3076fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    j(kZero, &null_arg);
3077eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
3078fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Bind(&null_arg);
3079fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
3080eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
3081fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
3082fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Store(out_off, scratch, 8);
3083fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3084fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3085eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Given a handle scope entry, load the associated reference.
3086eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::LoadReferenceFromHandleScope(ManagedRegister mout_reg,
3087fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                         ManagedRegister min_reg) {
3088fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister out_reg = mout_reg.AsX86_64();
3089fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister in_reg = min_reg.AsX86_64();
3090fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(out_reg.IsCpuRegister());
3091fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(in_reg.IsCpuRegister());
3092fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Label null_arg;
3093fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (!out_reg.Equals(in_reg)) {
3094fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
3095fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
3096fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
3097fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  j(kZero, &null_arg);
3098fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(out_reg.AsCpuRegister(), Address(in_reg.AsCpuRegister(), 0));
3099fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Bind(&null_arg);
3100fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3101fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3102fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
3103fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: not validating references
3104fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3105fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3106fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
3107fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: not validating references
3108fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3109fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3110fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Call(ManagedRegister mbase, Offset offset, ManagedRegister) {
3111fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister base = mbase.AsX86_64();
3112fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(base.IsCpuRegister());
3113fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  call(Address(base.AsCpuRegister(), offset.Int32Value()));
3114fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: place reference map on call
3115fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3116fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3117fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) {
3118dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
3119e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  movq(scratch, Address(CpuRegister(RSP), base));
3120fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  call(Address(scratch, offset));
3121fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3122fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3123dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CallFromThread64(ThreadOffset<8> offset, ManagedRegister /*mscratch*/) {
3124fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->call(Address::Absolute(offset, true));
3125fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3126fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3127fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::GetCurrentThread(ManagedRegister tr) {
3128dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(tr.AsX86_64().AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true));
3129fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3130fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3131dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::GetCurrentThread(FrameOffset offset, ManagedRegister mscratch) {
3132fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
3133dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(scratch.AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true));
3134dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), offset), scratch.AsCpuRegister());
3135fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3136fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3137dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Slowpath entered when Thread::Current()->_exception is non-null
3138dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass X86_64ExceptionSlowPath FINAL : public SlowPath {
3139dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers public:
3140dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  explicit X86_64ExceptionSlowPath(size_t stack_adjust) : stack_adjust_(stack_adjust) {}
3141dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  virtual void Emit(Assembler *sp_asm) OVERRIDE;
3142dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers private:
3143dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  const size_t stack_adjust_;
3144dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers};
3145dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
3146fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ExceptionPoll(ManagedRegister /*scratch*/, size_t stack_adjust) {
3147d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko  X86_64ExceptionSlowPath* slow = new (GetArena()) X86_64ExceptionSlowPath(stack_adjust);
3148fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  buffer_.EnqueueSlowPath(slow);
3149dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->cmpl(Address::Absolute(Thread::ExceptionOffset<8>(), true), Immediate(0));
3150fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  j(kNotEqual, slow->Entry());
3151fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3152fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3153dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64ExceptionSlowPath::Emit(Assembler *sasm) {
3154fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64Assembler* sp_asm = down_cast<X86_64Assembler*>(sasm);
3155fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#define __ sp_asm->
3156fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  __ Bind(&entry_);
3157fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Note: the return value is dead
3158fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (stack_adjust_ != 0) {  // Fix up the frame.
3159fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    __ DecreaseFrameSize(stack_adjust_);
3160fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
3161dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Pass exception as argument in RDI
3162dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  __ gs()->movq(CpuRegister(RDI), Address::Absolute(Thread::ExceptionOffset<8>(), true));
3163dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(8, pDeliverException), true));
3164fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // this call should never return
3165fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  __ int3();
3166fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#undef __
3167fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
3168fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
3169f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellvoid X86_64Assembler::AddConstantArea() {
3170d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko  ArrayRef<const int32_t> area = constant_area_.GetBuffer();
317139dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell  for (size_t i = 0, e = area.size(); i < e; i++) {
3172f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3173f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    EmitInt32(area[i]);
3174f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
3175f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
3176f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
31779c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendellsize_t ConstantArea::AppendInt32(int32_t v) {
31789c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendell  size_t result = buffer_.size() * elem_size_;
31799c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendell  buffer_.push_back(v);
31809c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendell  return result;
31819c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendell}
31829c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendell
31839c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendellsize_t ConstantArea::AddInt32(int32_t v) {
31849c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendell  // Look for an existing match.
318539dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell  for (size_t i = 0, e = buffer_.size(); i < e; i++) {
3186f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    if (v == buffer_[i]) {
3187f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell      return i * elem_size_;
3188f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    }
3189f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
3190f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
3191f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Didn't match anything.
31929c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendell  return AppendInt32(v);
3193f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
3194f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
31959c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendellsize_t ConstantArea::AddInt64(int64_t v) {
3196f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int32_t v_low = v;
3197f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int32_t v_high = v >> 32;
3198f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  if (buffer_.size() > 1) {
3199f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    // Ensure we don't pass the end of the buffer.
320039dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell    for (size_t i = 0, e = buffer_.size() - 1; i < e; i++) {
320139dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell      if (v_low == buffer_[i] && v_high == buffer_[i + 1]) {
3202f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell        return i * elem_size_;
3203f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell      }
3204f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    }
3205f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
3206f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
3207f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Didn't match anything.
32089c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendell  size_t result = buffer_.size() * elem_size_;
3209f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v_low);
3210f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v_high);
3211f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return result;
3212f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
3213f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
32149c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendellsize_t ConstantArea::AddDouble(double v) {
3215f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Treat the value as a 64-bit integer value.
3216f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return AddInt64(bit_cast<int64_t, double>(v));
3217f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
3218f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
32199c86b485bc6169eadf846dd5f7cdf0958fe1eb23Mark Mendellsize_t ConstantArea::AddFloat(float v) {
3220f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Treat the value as a 32-bit integer value.
3221f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return AddInt32(bit_cast<int32_t, float>(v));
3222f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
3223f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
3224fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}  // namespace x86_64
3225fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}  // namespace art
3226