assembler_x86_64.cc revision 0a18601f141d864a26d4b74ff5613e69ae411483
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
131dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movq(CpuRegister dst, CpuRegister src) {
132fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1335a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // 0x89 is movq r/m64 <- r64, with op1 in r/m and op2 in reg: so reverse EmitRex64
1345a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(src, dst);
135fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
136dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(src.LowBits(), dst.LowBits());
137fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
138fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
139fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
140dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movl(CpuRegister dst, CpuRegister src) {
141fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
142dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
143ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  EmitUint8(0x8B);
144ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  EmitRegisterOperand(dst.LowBits(), src.LowBits());
145fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
146fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
147fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
148dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movq(CpuRegister dst, const Address& src) {
149fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
150dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(dst, src);
151fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x8B);
152dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
153fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
154fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
155fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
156dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movl(CpuRegister dst, const Address& src) {
157fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
158dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
159fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x8B);
160dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
161fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
162fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
163fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
164dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movq(const Address& dst, CpuRegister src) {
165fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
166dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(src, dst);
167fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
168dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
169fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
170fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
171fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
172dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movl(const Address& dst, CpuRegister src) {
173fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
174dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(src, dst);
175fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
176dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
177fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
178fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
179fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movl(const Address& dst, const Immediate& imm) {
180fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
181dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
182fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC7);
183fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, dst);
184fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitImmediate(imm);
185fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
186fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
18771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
18871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::cmov(Condition c, CpuRegister dst, CpuRegister src) {
18971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  cmov(c, dst, src, true);
19071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
19171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
19271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::cmov(Condition c, CpuRegister dst, CpuRegister src, bool is64bit) {
19371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
19471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, is64bit, dst.NeedsRex(), false, src.NeedsRex());
19571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
19671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x40 + c);
19771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitRegisterOperand(dst.LowBits(), src.LowBits());
19871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
19971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
20071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
201dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxb(CpuRegister dst, CpuRegister src) {
202fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
203dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(dst, src);
204fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
205fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB6);
206dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
207fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
208fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
209fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
210dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxb(CpuRegister dst, const Address& src) {
211fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
212d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // Byte register is only in the source register form, so we don't use
213d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // EmitOptionalByteRegNormalizingRex32(dst, src);
214d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex32(dst, src);
215fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
216fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB6);
217dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
218fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
219fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
220fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
221dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxb(CpuRegister dst, CpuRegister src) {
222fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
223dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(dst, src);
224fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
225fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBE);
226dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
227fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
228fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
229fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
230dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxb(CpuRegister dst, const Address& src) {
231fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
232d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // Byte register is only in the source register form, so we don't use
233d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // EmitOptionalByteRegNormalizingRex32(dst, src);
234d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex32(dst, src);
235fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
236fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBE);
237dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
238fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
239fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
240fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
241dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movb(CpuRegister /*dst*/, const Address& /*src*/) {
242fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  LOG(FATAL) << "Use movzxb or movsxb instead.";
243fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
244fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
245fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
246dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movb(const Address& dst, CpuRegister src) {
247fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
248dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalByteRegNormalizingRex32(src, dst);
249fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x88);
250dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
251fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
252fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
253fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
254fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movb(const Address& dst, const Immediate& imm) {
255fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
25626a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOptionalRex32(dst);
257fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC6);
258dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(Register::RAX, dst);
259fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_int8());
260fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
261fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
262fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
263fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
264dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxw(CpuRegister dst, CpuRegister src) {
265fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
266dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
267fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
268fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB7);
269dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
270fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
271fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
272fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
273dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movzxw(CpuRegister dst, const Address& src) {
274fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
275dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
276fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
277fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB7);
278dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
279fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
280fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
281fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
282dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxw(CpuRegister dst, CpuRegister src) {
283fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
284dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
285fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
286fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBF);
287dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
288fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
289fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
290fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
291dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movsxw(CpuRegister dst, const Address& src) {
292fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
293dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
294fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
295fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xBF);
296dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
297fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
298fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
299fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
300dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movw(CpuRegister /*dst*/, const Address& /*src*/) {
301fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  LOG(FATAL) << "Use movzxw or movsxw instead.";
302fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
303fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
304fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
305dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movw(const Address& dst, CpuRegister src) {
306fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
307fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperandSizeOverride();
308e4ded41ae2648973d5fed8c6bafaebf917ea7d17Nicolas Geoffray  EmitOptionalRex32(src, dst);
309fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x89);
310dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
311fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
312fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
313fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
31426a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffrayvoid X86_64Assembler::movw(const Address& dst, const Immediate& imm) {
31526a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
31626a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOperandSizeOverride();
31726a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOptionalRex32(dst);
31826a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(0xC7);
31926a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitOperand(Register::RAX, dst);
320b6e7206ad7a426adda9cfd649a4ef969607d79d6Nicolas Geoffray  CHECK(imm.is_uint16() || imm.is_int16());
32126a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(imm.value() & 0xFF);
32226a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray  EmitUint8(imm.value() >> 8);
32326a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray}
32426a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray
32526a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray
326dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::leaq(CpuRegister dst, const Address& src) {
327fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
328dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(dst, src);
329fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x8D);
330dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
331fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
332fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
333fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
334748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffrayvoid X86_64Assembler::leal(CpuRegister dst, const Address& src) {
335748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
336748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitOptionalRex32(dst, src);
337748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitUint8(0x8D);
338748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray  EmitOperand(dst.LowBits(), src);
339748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray}
340748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray
341748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray
3427fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffrayvoid X86_64Assembler::movaps(XmmRegister dst, XmmRegister src) {
3437fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3447fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitOptionalRex32(dst, src);
3457fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitUint8(0x0F);
3467fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  EmitUint8(0x28);
347102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  EmitXmmRegisterOperand(dst.LowBits(), src);
3487fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray}
3497fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray
3507fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray
351fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(XmmRegister dst, const Address& src) {
352fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
353fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
354dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
355fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
356fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x10);
357dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
358fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
359fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
360fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
361fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(const Address& dst, XmmRegister src) {
362fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
363fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
364dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(src, dst);
365fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
366fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
367dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
368fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
369fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
370fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
371fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movss(XmmRegister dst, XmmRegister src) {
372fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
373fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
374851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);  // Movss is MR encoding instead of the usual RM.
375fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
376fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
377dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(src.LowBits(), dst);
378fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
379fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
380fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
381dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillainvoid X86_64Assembler::movsxd(CpuRegister dst, CpuRegister src) {
382dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
38357a88d4ac205874dc85d22f9f6a9ca3c4c373eebNicolas Geoffray  EmitRex64(dst, src);
384dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitUint8(0x63);
385dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitRegisterOperand(dst.LowBits(), src.LowBits());
386dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain}
387dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
388dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
389dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillainvoid X86_64Assembler::movsxd(CpuRegister dst, const Address& src) {
390dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
391dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitRex64(dst);
392dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitUint8(0x63);
393dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain  EmitOperand(dst.LowBits(), src);
394dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain}
395dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
396dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain
397dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::movd(XmmRegister dst, CpuRegister src) {
39871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  movd(dst, src, true);
39971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
40071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
40171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(CpuRegister dst, XmmRegister src) {
40271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  movd(dst, src, true);
40371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
40471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
40571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(XmmRegister dst, CpuRegister src, bool is64bit) {
406fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
407fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
40871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, is64bit, dst.NeedsRex(), false, src.NeedsRex());
409fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
410fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x6E);
411dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
412fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
413fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
41471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::movd(CpuRegister dst, XmmRegister src, bool is64bit) {
415fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
416fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
41771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, is64bit, src.NeedsRex(), false, dst.NeedsRex());
418fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
419fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x7E);
420dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), Operand(dst));
421fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
422fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
423fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
424fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addss(XmmRegister dst, XmmRegister src) {
425fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
426fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
427dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
428fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
429fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
430dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
431fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
433fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addss(XmmRegister dst, const Address& src) {
435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
436fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
437dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
438fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
439fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
440dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
441fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
442fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
443fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
444fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subss(XmmRegister dst, XmmRegister src) {
445fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
446fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
447dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
448fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
449fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
450dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
451fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
452fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
453fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subss(XmmRegister dst, const Address& src) {
455fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
456fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
457dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
458fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
459fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
460dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
461fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
462fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
463fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
464fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulss(XmmRegister dst, XmmRegister src) {
465fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
467dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
468fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
469fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
470dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
471fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
472fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
473fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulss(XmmRegister dst, const Address& src) {
475fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
476fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
477dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
478fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
479fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
480dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
482fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
483fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
484fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divss(XmmRegister dst, XmmRegister src) {
485fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
486fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
487dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
488fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
489fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
490dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
491fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
492fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
493fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
494fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divss(XmmRegister dst, const Address& src) {
495fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
496fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
497dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
498fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
499fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
500dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
501fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
502fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
503fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
504fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::flds(const Address& src) {
505fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
506fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
507fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, src);
508fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
509fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
510fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
51124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fsts(const Address& dst) {
51224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
51324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xD9);
51424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitOperand(2, dst);
51524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
51624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
51724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
518fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fstps(const Address& dst) {
519fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
520fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
521fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
522fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
523fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
524fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
525fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(XmmRegister dst, const Address& src) {
526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
527fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
528dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
529fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
530fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x10);
531dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
532fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
533fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
534fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
535fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(const Address& dst, XmmRegister src) {
536fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
537fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
538dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(src, dst);
539fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
540fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
541dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(src.LowBits(), dst);
542fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
543fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
544fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
545fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::movsd(XmmRegister dst, XmmRegister src) {
546fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
547fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
548851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);  // Movsd is MR encoding instead of the usual RM.
549fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
550fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x11);
551dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(src.LowBits(), dst);
552fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
553fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
554fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
555fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addsd(XmmRegister dst, XmmRegister src) {
556fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
557fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
558dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
559fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
560fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
561dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
562fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
563fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
564fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
565fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addsd(XmmRegister dst, const Address& src) {
566fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
567fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
568dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
569fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
570fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x58);
571dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
572fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
573fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
574fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subsd(XmmRegister dst, XmmRegister src) {
576fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
577fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
578dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
579fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
580fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
581dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
582fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
583fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
584fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
585fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::subsd(XmmRegister dst, const Address& src) {
586fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
587fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
588dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
589fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
590fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5C);
591dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
592fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
593fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
594fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
595fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulsd(XmmRegister dst, XmmRegister src) {
596fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
597fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
598dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
599fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
600fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
601dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
602fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
603fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
604fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
605fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mulsd(XmmRegister dst, const Address& src) {
606fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
607fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
608dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
609fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
610fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x59);
611dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
612fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
613fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
614fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
615fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divsd(XmmRegister dst, XmmRegister src) {
616fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
617fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
618dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
619fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
620fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
621dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
622fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
623fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
624fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::divsd(XmmRegister dst, const Address& src) {
626fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
627fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
628dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
629fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
630fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5E);
631dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
632fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
633fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
634fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
635dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src) {
6366d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  cvtsi2ss(dst, src, false);
6376d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain}
6386d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain
6396d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain
6406d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillainvoid X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src, bool is64bit) {
641fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
642fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
6436d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  if (is64bit) {
6446d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
6456d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    EmitRex64(dst, src);
6466d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  } else {
6476d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain    EmitOptionalRex32(dst, src);
6486d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain  }
649fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2A);
651dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
653fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
654fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
655dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsi2sd(XmmRegister dst, CpuRegister src) {
656647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  cvtsi2sd(dst, src, false);
657647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain}
658647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain
659647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain
660647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillainvoid X86_64Assembler::cvtsi2sd(XmmRegister dst, CpuRegister src, bool is64bit) {
661fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
662fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
663647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  if (is64bit) {
664647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
665647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    EmitRex64(dst, src);
666647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  } else {
667647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain    EmitOptionalRex32(dst, src);
668647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain  }
669fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
670fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2A);
671dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
672fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
673fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
674fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
675dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtss2si(CpuRegister dst, XmmRegister src) {
676fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
677fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
678dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
679fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
680fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2D);
681dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
682fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
683fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
684fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
685fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) {
686fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
687fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
688dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
689fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
690fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5A);
691dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
692fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
693fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
694fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
695dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvtsd2si(CpuRegister dst, XmmRegister src) {
696fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
697fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
698dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
699fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
700fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2D);
701dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
702fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
703fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
704fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
705dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvttss2si(CpuRegister dst, XmmRegister src) {
706624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  cvttss2si(dst, src, false);
707624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain}
708624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
709624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
710624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainvoid X86_64Assembler::cvttss2si(CpuRegister dst, XmmRegister src, bool is64bit) {
711fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
712fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
713624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  if (is64bit) {
714624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
715624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    EmitRex64(dst, src);
716624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  } else {
717624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain    EmitOptionalRex32(dst, src);
718624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  }
719fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
720fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2C);
721dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
722fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
723fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
724fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
725dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cvttsd2si(CpuRegister dst, XmmRegister src) {
7264c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  cvttsd2si(dst, src, false);
7274c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain}
7284c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain
7294c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain
7304c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillainvoid X86_64Assembler::cvttsd2si(CpuRegister dst, XmmRegister src, bool is64bit) {
731fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
732fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
7334c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  if (is64bit) {
7344c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    // Emit a REX.W prefix if the operand size is 64 bits.
7354c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    EmitRex64(dst, src);
7364c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  } else {
7374c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain    EmitOptionalRex32(dst, src);
7384c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain  }
739fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
740fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2C);
741dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
742fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
743fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
744fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
745fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) {
746fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
747fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
748dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
749fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
750fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x5A);
751dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
752fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
753fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
754fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
755fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) {
756fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
757fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
758dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
759fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
760fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xE6);
761dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
762fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
763fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
764fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
765fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::comiss(XmmRegister a, XmmRegister b) {
766fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
767dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(a, b);
768fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
769fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2F);
770dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(a.LowBits(), b);
771fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
772fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
773fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
774fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::comisd(XmmRegister a, XmmRegister b) {
775fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
776fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
777dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(a, b);
778fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
779fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2F);
780dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(a.LowBits(), b);
781fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
782fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
783ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravlevoid X86_64Assembler::ucomiss(XmmRegister a, XmmRegister b) {
784ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
785ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitOptionalRex32(a, b);
786ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x0F);
787ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x2E);
788ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitXmmRegisterOperand(a.LowBits(), b);
789ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle}
790ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
791ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
792ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravlevoid X86_64Assembler::ucomisd(XmmRegister a, XmmRegister b) {
793ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
794ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x66);
795ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitOptionalRex32(a, b);
796ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x0F);
797ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitUint8(0x2E);
798ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle  EmitXmmRegisterOperand(a.LowBits(), b);
799ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle}
800ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle
801fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
802fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendellvoid X86_64Assembler::roundsd(XmmRegister dst, XmmRegister src, const Immediate& imm) {
803fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
804fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x66);
805fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitOptionalRex32(dst, src);
806fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0F);
807fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x3A);
808fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0B);
809fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitXmmRegisterOperand(dst.LowBits(), src);
810fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(imm.value());
811fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell}
812fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
813fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
814fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendellvoid X86_64Assembler::roundss(XmmRegister dst, XmmRegister src, const Immediate& imm) {
815fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
816fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x66);
817fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitOptionalRex32(dst, src);
818fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0F);
819fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x3A);
820fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(0x0A);
821fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitXmmRegisterOperand(dst.LowBits(), src);
822fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  EmitUint8(imm.value());
823fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell}
824fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
825fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell
826fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
827fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
828fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
829dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
830fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
831fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x51);
832dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
833fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
834fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
835fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
836fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::sqrtss(XmmRegister dst, XmmRegister src) {
837fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
838fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF3);
839dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
840fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
841fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x51);
842dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
843fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
844fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
845fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
846fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorpd(XmmRegister dst, const Address& src) {
847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
849dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
850fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
851fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
852dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
854fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
855fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
856fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorpd(XmmRegister dst, XmmRegister src) {
857fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
858fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
859dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
860fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
861fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
862dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
863fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
864fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
865fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
866fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorps(XmmRegister dst, const Address& src) {
867fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
868dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
869fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
870fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
871dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
872fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
873fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
874fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
875fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::xorps(XmmRegister dst, XmmRegister src) {
876fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
877dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
878fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
879fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x57);
880dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitXmmRegisterOperand(dst.LowBits(), src);
881fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
882fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
883fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
884fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::andpd(XmmRegister dst, const Address& src) {
885fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
886fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x66);
887dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
888fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
889fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x54);
890dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), src);
891fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
892fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
89371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::andpd(XmmRegister dst, XmmRegister src) {
89471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
89571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x66);
89671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
89771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
89871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x54);
89971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
90071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
90171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
90271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::andps(XmmRegister dst, XmmRegister src) {
90371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
90471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
90571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
90671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x54);
90771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
90871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
90971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
91071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::orpd(XmmRegister dst, XmmRegister src) {
91171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
91271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x66);
91371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
91471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
91571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x56);
91671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
91771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
91871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
91971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::orps(XmmRegister dst, XmmRegister src) {
92071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
92171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex32(dst, src);
92271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
92371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x56);
92471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitXmmRegisterOperand(dst.LowBits(), src);
92571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
926fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
927fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fldl(const Address& src) {
928fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
929fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
930fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(0, src);
931fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
932fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
933fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
93424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fstl(const Address& dst) {
93524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
93624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDD);
93724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitOperand(2, dst);
93824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
93924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
94024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
941fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fstpl(const Address& dst) {
942fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
943fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
944fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
945fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
946fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
947fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
94824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fstsw() {
94924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
95024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0x9B);
95124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDF);
95224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xE0);
95324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
95424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
95524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
956fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fnstcw(const Address& dst) {
957fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
958fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
959fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(7, dst);
960fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
961fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
962fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
963fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fldcw(const Address& src) {
964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
966fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, src);
967fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
968fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
969fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
970fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fistpl(const Address& dst) {
971fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
972fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDF);
973fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(7, dst);
974fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
975fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
976fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
977fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fistps(const Address& dst) {
978fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
979fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDB);
980fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, dst);
981fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
982fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
983fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
984fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fildl(const Address& src) {
985fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
986fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDF);
987fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, src);
988fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
989fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
990fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
9910a18601f141d864a26d4b74ff5613e69ae411483Roland Levillainvoid X86_64Assembler::filds(const Address& src) {
9920a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
9930a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  EmitUint8(0xDB);
9940a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain  EmitOperand(0, src);
9950a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain}
9960a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain
9970a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain
998fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fincstp() {
999fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1000fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1001fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1002fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1004fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1005fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ffree(const Immediate& index) {
1006fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(index.value(), 7);
1007fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1008fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
1009fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC0 + index.value());
1010fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1011fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1012fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1013fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fsin() {
1014fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1015fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1016fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFE);
1017fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1019fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1020fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fcos() {
1021fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1022fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1023fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1024fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1025fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1026fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1027fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fptan() {
1028fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1029fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1030fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
1031fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1032fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
103324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fucompp() {
103424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
103524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDA);
103624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xE9);
103724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
103824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
103924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
104024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fprem() {
104124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
104224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xD9);
104324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xF8);
104424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
104524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
1046fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1047dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xchgl(CpuRegister dst, CpuRegister src) {
1048fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1049851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // There is a short version for rax.
1050851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't
1051851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // work.
1052851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool src_rax = src.AsRegister() == RAX;
1053851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool dst_rax = dst.AsRegister() == RAX;
1054851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  if (src_rax || dst_rax) {
1055851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOptionalRex32(src_rax ? dst : src);
1056851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits()));
1057851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    return;
1058851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1059851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1060851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // General case.
1061851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);
1062fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x87);
1063851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
1064fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1065fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1066ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1067ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffrayvoid X86_64Assembler::xchgq(CpuRegister dst, CpuRegister src) {
1068ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1069851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // There is a short version for rax.
1070851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't
1071851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // work.
1072851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool src_rax = src.AsRegister() == RAX;
1073851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool dst_rax = dst.AsRegister() == RAX;
1074851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  if (src_rax || dst_rax) {
1075851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // If src == target, emit a nop instead.
1076851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    if (src_rax && dst_rax) {
1077851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitUint8(0x90);
1078851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    } else {
1079851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitRex64(src_rax ? dst : src);
1080851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits()));
1081851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    }
1082851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    return;
1083851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1084851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1085851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // General case.
1086851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRex64(src, dst);
1087ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  EmitUint8(0x87);
1088851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
1089ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray}
1090ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1091ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1092dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xchgl(CpuRegister reg, const Address& address) {
1093fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1094dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1095fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x87);
1096dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1097fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1098fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1099fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
11003c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffrayvoid X86_64Assembler::cmpw(const Address& address, const Immediate& imm) {
11013c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
11023c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitOptionalRex32(address);
11033c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitUint8(0x66);
11043c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitComplex(7, address, imm);
11053c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray}
11063c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
11073c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
1108dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg, const Immediate& imm) {
1109fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1110dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1111fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(7, Operand(reg), imm);
1112fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1113fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1114fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1115dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg0, CpuRegister reg1) {
1116fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1117dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg0, reg1);
1118fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x3B);
1119dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg0.LowBits(), Operand(reg1));
1120fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1121fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1122fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1123dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg, const Address& address) {
1124fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1125dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1126fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x3B);
1127dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1128fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1129fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1130fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1131d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpl(const Address& address, CpuRegister reg) {
1132d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1133d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex32(reg, address);
1134d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x39);
1135d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOperand(reg.LowBits(), address);
1136d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1137d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1138d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1139d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpl(const Address& address, const Immediate& imm) {
1140d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1141d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex32(address);
1142d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitComplex(7, address, imm);
1143d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1144d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1145d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
11465a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::cmpq(CpuRegister reg0, CpuRegister reg1) {
11475a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
11485a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(reg0, reg1);
11495a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x3B);
11505a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitOperand(reg0.LowBits(), Operand(reg1));
11515a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
11525a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
11535a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
115496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::cmpq(CpuRegister reg, const Immediate& imm) {
115596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
115696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  CHECK(imm.is_int32());  // cmpq only supports 32b immediate.
115796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(reg);
115896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitComplex(7, Operand(reg), imm);
115996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
116096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
116196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
116296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::cmpq(CpuRegister reg, const Address& address) {
116396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
116496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(reg);
116596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x3B);
116696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
116796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
116896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
116996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
1170d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpq(const Address& address, const Immediate& imm) {
1171d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  CHECK(imm.is_int32());  // cmpq only supports 32b immediate.
1172d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1173d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(address);
1174d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitComplex(7, address, imm);
1175d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1176d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1177d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1178dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister dst, CpuRegister src) {
1179fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1180dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1181fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x03);
1182dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
1183fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1184fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1185fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1186dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister reg, const Address& address) {
1187fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1188dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1189fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x03);
1190dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1191fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1192fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1193fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1194dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::testl(CpuRegister reg1, CpuRegister reg2) {
1195fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1196dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg1, reg2);
1197fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x85);
1198dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(reg1.LowBits(), reg2.LowBits());
1199fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1200fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1201fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1202cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravlevoid X86_64Assembler::testl(CpuRegister reg, const Address& address) {
1203cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1204cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitOptionalRex32(reg, address);
1205cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitUint8(0x85);
1206cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitOperand(reg.LowBits(), address);
1207cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle}
1208cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle
1209cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle
1210dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::testl(CpuRegister reg, const Immediate& immediate) {
1211fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1212fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // For registers that have a byte variant (RAX, RBX, RCX, and RDX)
1213dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // we only test the byte CpuRegister to keep the encoding short.
1214dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (immediate.is_uint8() && reg.AsRegister() < 4) {
1215fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use zero-extended 8-bit immediate.
1216dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    if (reg.AsRegister() == RAX) {
1217fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xA8);
1218fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1219fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xF6);
1220dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      EmitUint8(0xC0 + reg.AsRegister());
1221fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1222fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(immediate.value() & 0xFF);
1223dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  } else if (reg.AsRegister() == RAX) {
1224fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use short form if the destination is RAX.
1225fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xA9);
1226fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
1227fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1228dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitOptionalRex32(reg);
1229fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xF7);
1230fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(0, Operand(reg));
1231fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
1232fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1233fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1234fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1235fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1236d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::testq(CpuRegister reg1, CpuRegister reg2) {
1237d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1238d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(reg1, reg2);
1239d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x85);
1240d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRegisterOperand(reg1.LowBits(), reg2.LowBits());
1241d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1242d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1243d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1244f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffrayvoid X86_64Assembler::testq(CpuRegister reg, const Address& address) {
1245f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1246f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitRex64(reg);
1247f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitUint8(0x85);
1248f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
1249f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray}
1250f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1251f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1252dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::andl(CpuRegister dst, CpuRegister src) {
1253fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1254dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1255fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x23);
1256dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1257fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1258fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1259fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
12609574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::andl(CpuRegister reg, const Address& address) {
12619574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12629574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
12639574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x23);
12649574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
12659574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
12669574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
12679574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1268dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::andl(CpuRegister dst, const Immediate& imm) {
1269fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1270dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
1271fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(4, Operand(dst), imm);
1272fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1273fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1274fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1275412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffrayvoid X86_64Assembler::andq(CpuRegister reg, const Immediate& imm) {
1276412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1277412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  CHECK(imm.is_int32());  // andq only supports 32b immediate.
1278412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitRex64(reg);
1279412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitComplex(4, Operand(reg), imm);
1280412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray}
1281412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
1282412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
12839574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::andq(CpuRegister dst, CpuRegister src) {
12849574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12859574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitRex64(dst, src);
12869574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x23);
12879574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
12889574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
12899574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
12909574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1291dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::orl(CpuRegister dst, CpuRegister src) {
1292fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1293dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1294fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0B);
1295dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1296fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1297fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1298fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
12999574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::orl(CpuRegister reg, const Address& address) {
13009574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13019574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
13029574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x0B);
13039574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
13049574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13059574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13069574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1307dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::orl(CpuRegister dst, const Immediate& imm) {
1308fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1309dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
1310fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(1, Operand(dst), imm);
1311fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1312fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1313fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
13143f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendellvoid X86_64Assembler::orq(CpuRegister dst, const Immediate& imm) {
13153f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13163f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  CHECK(imm.is_int32());  // orq only supports 32b immediate.
13173f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitRex64(dst);
13183f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitComplex(1, Operand(dst), imm);
13193f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell}
13203f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
13213f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
13229574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::orq(CpuRegister dst, CpuRegister src) {
13239574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13249574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitRex64(dst, src);
13259574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x0B);
13269574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
13279574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13289574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13299574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1330dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xorl(CpuRegister dst, CpuRegister src) {
1331fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1332dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1333fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x33);
1334dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1335fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1336fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
13375a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
13389574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::xorl(CpuRegister reg, const Address& address) {
13399574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13409574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
13419574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x33);
13429574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
13439574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13449574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13459574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13469574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::xorl(CpuRegister dst, const Immediate& imm) {
13479574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13489574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(dst);
13499574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitComplex(6, Operand(dst), imm);
13509574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13519574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13529574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1353412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffrayvoid X86_64Assembler::xorq(CpuRegister dst, CpuRegister src) {
1354412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1355412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitRex64(dst, src);
1356412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitUint8(0x33);
1357412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
1358412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray}
1359412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
1360412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
13615a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::xorq(CpuRegister dst, const Immediate& imm) {
13625a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13635a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // xorq only supports 32b immediate.
13645a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(dst);
13655a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitComplex(6, Operand(dst), imm);
13665a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
13675a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1368dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#if 0
1369dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::rex(bool force, bool w, Register* r, Register* x, Register* b) {
1370fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // REX.WRXB
1371fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // W - 64-bit operand
1372fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // R - MODRM.reg
1373fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // X - SIB.index
1374fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // B - MODRM.rm/SIB.base
1375dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = force ? 0x40 : 0;
1376dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
1377fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x48;  // REX.W000
1378fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1379dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (r != nullptr && *r >= Register::R8 && *r < Register::kNumberOfCpuRegisters) {
1380fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x44;  // REX.0R00
1381dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *r = static_cast<Register>(*r - 8);
1382fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1383dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (x != nullptr && *x >= Register::R8 && *x < Register::kNumberOfCpuRegisters) {
1384dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x42;  // REX.00X0
1385dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *x = static_cast<Register>(*x - 8);
1386dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1387dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (b != nullptr && *b >= Register::R8 && *b < Register::kNumberOfCpuRegisters) {
1388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x41;  // REX.000B
1389dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *b = static_cast<Register>(*b - 8);
1390fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1391fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (rex != 0) {
1392fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(rex);
1393fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1394fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1395fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1396dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::rex_reg_mem(bool force, bool w, Register* dst, const Address& mem) {
1397dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // REX.WRXB
1398dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // W - 64-bit operand
1399dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // R - MODRM.reg
1400dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // X - SIB.index
1401dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // B - MODRM.rm/SIB.base
1402dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = mem->rex();
1403dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (force) {
1404dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x40;  // REX.0000
1405dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1406dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
1407dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x48;  // REX.W000
1408dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1409dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (dst != nullptr && *dst >= Register::R8 && *dst < Register::kNumberOfCpuRegisters) {
1410dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x44;  // REX.0R00
1411dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *dst = static_cast<Register>(*dst - 8);
1412dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1413dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (rex != 0) {
1414dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitUint8(rex);
1415dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1416dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
1417dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1418dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid rex_mem_reg(bool force, bool w, Address* mem, Register* src);
1419dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#endif
1420dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1421dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister reg, const Immediate& imm) {
1422fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1423dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1424fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, Operand(reg), imm);
1425fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1426fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1427fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1428dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addq(CpuRegister reg, const Immediate& imm) {
1429fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14305a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // addq only supports 32b immediate.
1431dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(reg);
1432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, Operand(reg), imm);
1433fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
143696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::addq(CpuRegister dst, const Address& address) {
143796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
143896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(dst);
143996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x03);
144096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(dst.LowBits(), address);
144196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
144296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
144396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
14445a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::addq(CpuRegister dst, CpuRegister src) {
14455a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14465a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // 0x01 is addq r/m64 <- r/m64 + r64, with op1 in r/m and op2 in reg: so reverse EmitRex64
14475a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(src, dst);
14485a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x01);
14495a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
14505a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
14515a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14525a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1453dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(const Address& address, CpuRegister reg) {
1454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1455dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1456fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x01);
1457dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1458fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1459fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1460fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1461fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addl(const Address& address, const Immediate& imm) {
1462fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1463dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1464fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, address, imm);
1465fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1467fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1468dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister dst, CpuRegister src) {
1469fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1470dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1471fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2B);
1472dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1473fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1475fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1476dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister reg, const Immediate& imm) {
1477fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1478dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1479fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(5, Operand(reg), imm);
1480fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1482fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
14835a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::subq(CpuRegister reg, const Immediate& imm) {
14845a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14855a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // subq only supports 32b immediate.
14865a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(reg);
14875a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitComplex(5, Operand(reg), imm);
14885a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
14895a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14905a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14915a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::subq(CpuRegister dst, CpuRegister src) {
14925a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14935a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(dst, src);
14945a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x2B);
14955a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRegisterOperand(dst.LowBits(), src.LowBits());
14965a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
14975a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14985a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
149996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::subq(CpuRegister reg, const Address& address) {
150096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
150196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(reg);
150296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x2B);
150396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(reg.LowBits() & 7, address);
150496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
150596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
150696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
1507dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister reg, const Address& address) {
1508fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1509dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1510fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2B);
1511dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1512fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1513fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1514fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1515fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cdq() {
1516fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1517fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x99);
1518fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1519fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1520fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1521d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cqo() {
1522d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1523d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64();
1524d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x99);
1525d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1526d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1527d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1528dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::idivl(CpuRegister reg) {
1529fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1530dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1531fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1532dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xF8 | reg.LowBits());
1533fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1534fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1535fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1536d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::idivq(CpuRegister reg) {
1537d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1538d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(reg);
1539d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0xF7);
1540d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0xF8 | reg.LowBits());
1541d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1542d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1543d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1544dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister dst, CpuRegister src) {
1545fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1546dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1547fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1548fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAF);
1549dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1550fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1551fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1552dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg, const Immediate& imm) {
1553fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1554851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  CHECK(imm.is_int32());  // imull only supports 32b immediate.
1555851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1556b5de00f1c8f53e6552f1778702673c6274a98bb3Nicolas Geoffray  EmitOptionalRex32(reg, reg);
1557851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1558851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // See whether imm can be represented as a sign-extended 8bit value.
1559851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  int32_t v32 = static_cast<int32_t>(imm.value());
1560ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  if (IsInt<8>(v32)) {
1561851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Sign-extension works.
1562851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x6B);
1563851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOperand(reg.LowBits(), Operand(reg));
1564851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(static_cast<uint8_t>(v32 & 0xFF));
1565851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
1566851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Not representable, use full immediate.
1567851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x69);
1568851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOperand(reg.LowBits(), Operand(reg));
1569851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitImmediate(imm);
1570851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1571fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1572fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1573fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1574dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg, const Address& address) {
1575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1576dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1577fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1578fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAF);
1579dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1580fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1581fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1582fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
158334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister dst, CpuRegister src) {
158434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
158534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRex64(dst, src);
158634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0x0F);
158734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0xAF);
158834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRegisterOperand(dst.LowBits(), src.LowBits());
158934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
159034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
159134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
159234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister reg, const Immediate& imm) {
15933f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  imulq(reg, reg, imm);
15943f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell}
15953f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
15963f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendellvoid X86_64Assembler::imulq(CpuRegister dst, CpuRegister reg, const Immediate& imm) {
159734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
159834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  CHECK(imm.is_int32());  // imulq only supports 32b immediate.
1599851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
16003f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitRex64(dst, reg);
1601851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1602851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // See whether imm can be represented as a sign-extended 8bit value.
1603851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  int64_t v64 = imm.value();
1604ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  if (IsInt<8>(v64)) {
1605851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Sign-extension works.
1606851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x6B);
16073f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell    EmitOperand(dst.LowBits(), Operand(reg));
1608851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(static_cast<uint8_t>(v64 & 0xFF));
1609851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
1610851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Not representable, use full immediate.
1611851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x69);
16123f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell    EmitOperand(dst.LowBits(), Operand(reg));
1613851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitImmediate(imm);
1614851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
161534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
161634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
161734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister reg, const Address& address) {
161834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
161934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRex64(reg, address);
162034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0x0F);
162134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0xAF);
162234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitOperand(reg.LowBits(), address);
162334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
162434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
162534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
1626dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg) {
1627fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1628dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1629fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1630fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, Operand(reg));
1631fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1632fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1633fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
16340f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchezvoid X86_64Assembler::imulq(CpuRegister reg) {
16350f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16360f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitRex64(reg);
16370f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitUint8(0xF7);
16380f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitOperand(5, Operand(reg));
16390f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez}
16400f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez
16410f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez
1642fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::imull(const Address& address) {
1643fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1644dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1645fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1646fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, address);
1647fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1648fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1649fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1650dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::mull(CpuRegister reg) {
1651fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1652dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1653fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1654fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, Operand(reg));
1655fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1656fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1657fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1658fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mull(const Address& address) {
1659fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1660dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1661fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1662fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, address);
1663fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1664fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1665fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1666dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shll(CpuRegister reg, const Immediate& imm) {
16671a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 4, reg, imm);
1668fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1669fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1670fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
16719aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shlq(CpuRegister reg, const Immediate& imm) {
16729aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 4, reg, imm);
16739aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
16749aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
16759aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
1676dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shll(CpuRegister operand, CpuRegister shifter) {
16779aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 4, operand, shifter);
16789aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
16799aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
16809aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
16819aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shlq(CpuRegister operand, CpuRegister shifter) {
16829aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 4, operand, shifter);
1683fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1684fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1685fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1686dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shrl(CpuRegister reg, const Immediate& imm) {
16871a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 5, reg, imm);
16881a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray}
16891a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray
16901a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray
16911a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffrayvoid X86_64Assembler::shrq(CpuRegister reg, const Immediate& imm) {
16921a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(true, 5, reg, imm);
1693fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1694fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1695fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1696dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shrl(CpuRegister operand, CpuRegister shifter) {
16979aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 5, operand, shifter);
16989aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
16999aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17009aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17019aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shrq(CpuRegister operand, CpuRegister shifter) {
17029aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 5, operand, shifter);
1703fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1704fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1705fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1706dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::sarl(CpuRegister reg, const Immediate& imm) {
17071a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 7, reg, imm);
1708fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1709fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1710fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1711dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::sarl(CpuRegister operand, CpuRegister shifter) {
17129aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 7, operand, shifter);
17139aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
17149aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17159aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17169aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::sarq(CpuRegister reg, const Immediate& imm) {
17179aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 7, reg, imm);
17189aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
17199aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17209aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17219aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::sarq(CpuRegister operand, CpuRegister shifter) {
17229aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 7, operand, shifter);
1723fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1724fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1725fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1726dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::negl(CpuRegister reg) {
1727fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1728dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1729fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1730fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, Operand(reg));
1731fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1732fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1733705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
17342e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillainvoid X86_64Assembler::negq(CpuRegister reg) {
17352e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
17362e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitRex64(reg);
17372e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitUint8(0xF7);
17382e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitOperand(3, Operand(reg));
17392e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain}
17402e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain
1741fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1742dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::notl(CpuRegister reg) {
1743fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1744dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1745fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1746dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xD0 | reg.LowBits());
1747fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1748fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1749fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1750705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillainvoid X86_64Assembler::notq(CpuRegister reg) {
1751705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1752705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitRex64(reg);
1753705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitUint8(0xF7);
1754705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitOperand(2, Operand(reg));
1755705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain}
1756705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
1757705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
1758fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::enter(const Immediate& imm) {
1759fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1760fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC8);
1761ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  CHECK(imm.is_uint16()) << imm.value();
1762fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
1763fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8((imm.value() >> 8) & 0xFF);
1764fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x00);
1765fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1766fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1767fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1768fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::leave() {
1769fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1770fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC9);
1771fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1772fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1773fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1774fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ret() {
1775fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1776fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC3);
1777fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1778fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1779fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1780fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ret(const Immediate& imm) {
1781fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1782fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC2);
1783fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_uint16());
1784fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
1785fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8((imm.value() >> 8) & 0xFF);
1786fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1787fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1788fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1789fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1790fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::nop() {
1791fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1792fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x90);
1793fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1794fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1795fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1796fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::int3() {
1797fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1798fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xCC);
1799fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1800fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1801fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1802fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::hlt() {
1803fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1804fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF4);
1805fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1806fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1807fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1808fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::j(Condition condition, Label* label) {
1809fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1810fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
1811fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kShortSize = 2;
1812fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kLongSize = 6;
1813fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
1814fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
1815ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe    if (IsInt<8>(offset - kShortSize)) {
1816fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x70 + condition);
1817fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8((offset - kShortSize) & 0xFF);
1818fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1819fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x0F);
1820fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x80 + condition);
1821fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitInt32(offset - kLongSize);
1822fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1823fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1824fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x0F);
1825fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x80 + condition);
1826fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
1827fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1828fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1829fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1830fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1831dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::jmp(CpuRegister reg) {
1832fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1833dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1834fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1835dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(4, reg.LowBits());
1836fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1837fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1838fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::jmp(const Address& address) {
1839fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1840dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1841fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1842fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, address);
1843fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1844fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1845fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::jmp(Label* label) {
1846fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
1848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kShortSize = 2;
1849fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kLongSize = 5;
1850fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
1851fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
1852ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe    if (IsInt<8>(offset - kShortSize)) {
1853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xEB);
1854fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8((offset - kShortSize) & 0xFF);
1855fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1856fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xE9);
1857fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitInt32(offset - kLongSize);
1858fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1859fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1860fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xE9);
1861fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
1862fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1863fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1864fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1865fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1866fca82208f7128fcda09b6a4743199308332558a2Dmitry PetrochenkoX86_64Assembler* X86_64Assembler::lock() {
1867fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1868fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF0);
1869fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return this;
1870fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1871fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1872fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1873dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpxchgl(const Address& address, CpuRegister reg) {
1874fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
187558d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitOptionalRex32(reg, address);
187658d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitUint8(0x0F);
187758d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitUint8(0xB1);
187858d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitOperand(reg.LowBits(), address);
187958d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell}
188058d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
188158d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
188258d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendellvoid X86_64Assembler::cmpxchgq(const Address& address, CpuRegister reg) {
188358d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
188458d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitRex64(reg, address);
1885fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1886fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB1);
1887dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1888fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1889fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
189058d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
1891fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mfence() {
1892fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1893fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1894fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAE);
1895fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF0);
1896fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1897fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
18985a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1899fca82208f7128fcda09b6a4743199308332558a2Dmitry PetrochenkoX86_64Assembler* X86_64Assembler::gs() {
19005a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // TODO: gs is a prefix and not an instruction
1901fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1902fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x65);
1903fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return this;
1904fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1905fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
19065a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1907dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::AddImmediate(CpuRegister reg, const Immediate& imm) {
1908fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int value = imm.value();
1909dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (value != 0) {
1910dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    if (value > 0) {
1911fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      addl(reg, imm);
1912dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    } else {
1913fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      subl(reg, Immediate(value));
1914fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1915fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1916fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1917fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1918fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
19195a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::setcc(Condition condition, CpuRegister dst) {
19205a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
19215a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // RSP, RBP, RDI, RSI need rex prefix (else the pattern encodes ah/bh/ch/dh).
19225a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (dst.NeedsRex() || dst.AsRegister() > 3) {
19235a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitOptionalRex(true, false, false, false, dst.NeedsRex());
19245a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
19255a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x0F);
19265a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x90 + condition);
19275a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0xC0 + dst.LowBits());
19285a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
19295a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
193071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::bswapl(CpuRegister dst) {
193171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
193271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, false, false, false, dst.NeedsRex());
193371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
193471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0xC8 + dst.LowBits());
193571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
193671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
193771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::bswapq(CpuRegister dst) {
193871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
193971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, true, false, false, dst.NeedsRex());
194071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
194171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0xC8 + dst.LowBits());
194271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
194371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
19445a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1945fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
1946fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: Need to have a code constants table.
1947fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int64_t constant = bit_cast<int64_t, double>(value);
1948fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Immediate(High32Bits(constant)));
1949fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Immediate(Low32Bits(constant)));
1950dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movsd(dst, Address(CpuRegister(RSP), 0));
195113735955f39b3b304c37d2b2840663c131262c18Ian Rogers  addq(CpuRegister(RSP), Immediate(2 * sizeof(intptr_t)));
1952fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1953fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1954fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1955fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Align(int alignment, int offset) {
1956fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(IsPowerOfTwo(alignment));
1957fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit nop instruction until the real position is aligned.
1958fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) {
1959fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    nop();
1960fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1961fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1962fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1963fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Bind(Label* label) {
1965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int bound = buffer_.Size();
1966fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(!label->IsBound());  // Labels can only be bound once.
1967fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  while (label->IsLinked()) {
1968fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int position = label->LinkPosition();
1969fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int next = buffer_.Load<int32_t>(position);
1970fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    buffer_.Store<int32_t>(position, bound - (position + 4));
1971fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    label->position_ = next;
1972fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1973fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  label->BindTo(bound);
1974fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1975fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1976fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1977dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOperand(uint8_t reg_or_opcode, const Operand& operand) {
1978fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GE(reg_or_opcode, 0);
1979fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(reg_or_opcode, 8);
1980fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  const int length = operand.length_;
1981fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GT(length, 0);
1982fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit the ModRM byte updated with the given reg value.
1983fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(operand.encoding_[0] & 0x38, 0);
1984fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(operand.encoding_[0] + (reg_or_opcode << 3));
1985fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit the rest of the encoded operand.
1986fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (int i = 1; i < length; i++) {
1987fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(operand.encoding_[i]);
1988fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1989f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  AssemblerFixup* fixup = operand.GetFixup();
1990f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  if (fixup != nullptr) {
1991f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    EmitFixup(fixup);
1992f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
1993fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1994fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1995fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1996fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitImmediate(const Immediate& imm) {
19975a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (imm.is_int32()) {
19985a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt32(static_cast<int32_t>(imm.value()));
19995a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  } else {
20005a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt64(imm.value());
20015a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
2002fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2004fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2005dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitComplex(uint8_t reg_or_opcode,
2006dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                  const Operand& operand,
2007dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                  const Immediate& immediate) {
2008fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GE(reg_or_opcode, 0);
2009fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(reg_or_opcode, 8);
2010fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (immediate.is_int8()) {
2011fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use sign-extended 8-bit immediate.
2012fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x83);
2013fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, operand);
2014fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(immediate.value() & 0xFF);
2015dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  } else if (operand.IsRegister(CpuRegister(RAX))) {
2016fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use short form if the destination is eax.
2017fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x05 + (reg_or_opcode << 3));
2018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
2019fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2020fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x81);
2021fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, operand);
2022fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
2023fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2024fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2025fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2026fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2027fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitLabel(Label* label, int instruction_size) {
2028fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
2029fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
2030fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
2031fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitInt32(offset - instruction_size);
2032fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2033fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
2034fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2035fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2036fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2037fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2038fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitLabelLink(Label* label) {
2039fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(!label->IsBound());
2040fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int position = buffer_.Size();
2041fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitInt32(label->position_);
2042fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  label->LinkTo(position);
2043fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2044fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2045fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
20461a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffrayvoid X86_64Assembler::EmitGenericShift(bool wide,
20471a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       int reg_or_opcode,
20481a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister reg,
20491a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       const Immediate& imm) {
2050fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2051fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_int8());
20521a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  if (wide) {
20531a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray    EmitRex64(reg);
2054851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
2055851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOptionalRex32(reg);
20561a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  }
2057fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (imm.value() == 1) {
2058fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xD1);
2059fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, Operand(reg));
2060fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2061fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xC1);
2062fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, Operand(reg));
2063fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(imm.value() & 0xFF);
2064fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2065fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2066fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2067fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
20689aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::EmitGenericShift(bool wide,
20699aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle                                       int reg_or_opcode,
20701a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister operand,
20711a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister shifter) {
2072fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2073dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CHECK_EQ(shifter.AsRegister(), RCX);
20749aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  if (wide) {
20759aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle    EmitRex64(operand);
20769aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  } else {
20779aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle    EmitOptionalRex32(operand);
20789aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  }
2079fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD3);
2080fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(reg_or_opcode, Operand(operand));
2081fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2082fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2083dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) {
2084dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // REX.WRXB
2085dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // W - 64-bit operand
2086dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // R - MODRM.reg
2087dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // X - SIB.index
2088dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // B - MODRM.rm/SIB.base
2089dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = force ? 0x40 : 0;
2090dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
2091dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x48;  // REX.W000
2092dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2093dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (r) {
2094dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x44;  // REX.0R00
2095dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2096dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (x) {
2097dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x42;  // REX.00X0
2098dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2099dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (b) {
2100dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x41;  // REX.000B
2101dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2102dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (rex != 0) {
2103dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitUint8(rex);
2104dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2105dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2106dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2107dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister reg) {
2108fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov  EmitOptionalRex(false, false, false, false, reg.NeedsRex());
2109dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2110dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2111dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, CpuRegister src) {
2112dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2113dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2114dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2115dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, XmmRegister src) {
2116dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2117dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2118dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2119dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, XmmRegister src) {
2120dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2121dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2122dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2123dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, CpuRegister src) {
2124dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2125dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2126dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2127dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(const Operand& operand) {
2128790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2129790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2130790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2131790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2132dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2133dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2134dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, const Operand& operand) {
2135790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2136790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2137790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2138790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2139790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2140790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2141790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2142dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2143dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2144dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, const Operand& operand) {
2145790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2146790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2147790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2148790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2149790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2150790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2151790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2152dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2153dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2154d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::EmitRex64() {
2155d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex(false, true, false, false, false);
2156d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
2157d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
2158dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister reg) {
2159fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov  EmitOptionalRex(false, true, false, false, reg.NeedsRex());
2160dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2161fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov
2162d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::EmitRex64(const Operand& operand) {
2163d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  uint8_t rex = operand.rex();
2164d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  rex |= 0x48;  // REX.W000
2165d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(rex);
2166d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
2167d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
2168dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister dst, CpuRegister src) {
2169dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2170dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2171dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2172102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffrayvoid X86_64Assembler::EmitRex64(XmmRegister dst, CpuRegister src) {
2173102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2174102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray}
2175102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray
2176624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainvoid X86_64Assembler::EmitRex64(CpuRegister dst, XmmRegister src) {
2177624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2178624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain}
2179624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
2180dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister dst, const Operand& operand) {
2181790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = 0x48 | operand.rex();  // REX.W000
2182790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2183790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2184790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2185790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2186790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2187790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2188dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2189dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2190dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, CpuRegister src) {
2191d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // For src, SPL, BPL, SIL, DIL need the rex prefix.
2192d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  bool force = src.AsRegister() > 3;
2193d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex(force, false, dst.NeedsRex(), false, src.NeedsRex());
2194dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2195dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2196dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, const Operand& operand) {
2197d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  uint8_t rex = operand.rex();
2198d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // For dst, SPL, BPL, SIL, DIL need the rex prefix.
2199d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  bool force = dst.AsRegister() > 3;
2200d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  if (force) {
2201d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu    rex |= 0x40;  // REX.0000
2202d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  }
2203790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2204790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2205790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2206790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2207790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2208790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2209dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2210dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2211dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckystatic dwarf::Reg DWARFReg(Register reg) {
2212dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  return dwarf::Reg::X86_64Core(static_cast<int>(reg));
2213dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}
2214dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckystatic dwarf::Reg DWARFReg(FloatRegister reg) {
2215dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  return dwarf::Reg::X86_64Fp(static_cast<int>(reg));
2216dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}
2217dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
2218790a6b7312979513710c366b411ba6791ddf78c2Ian Rogersconstexpr size_t kFramePointerSize = 8;
2219790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers
2220fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
2221790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                                 const std::vector<ManagedRegister>& spill_regs,
2222790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                                 const ManagedRegisterEntrySpills& entry_spills) {
22238c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky  DCHECK_EQ(buffer_.Size(), 0U);  // Nothing emitted yet.
2224dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.SetCurrentCFAOffset(8);  // Return address on stack.
2225fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(frame_size, kStackAlignment);
2226c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int gpr_count = 0;
2227fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (int i = spill_regs.size() - 1; i >= 0; --i) {
2228c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2229c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsCpuRegister()) {
2230c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      pushq(spill.AsCpuRegister());
2231c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      gpr_count++;
2232dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.AdjustCFAOffset(kFramePointerSize);
2233dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.RelOffset(DWARFReg(spill.AsCpuRegister().AsRegister()), 0);
2234c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2235fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
22368c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky  // return address then method on stack.
2237c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t rest_of_frame = static_cast<int64_t>(frame_size)
2238c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov                          - (gpr_count * kFramePointerSize)
2239c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov                          - kFramePointerSize /*return address*/;
2240c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  subq(CpuRegister(RSP), Immediate(rest_of_frame));
2241dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(rest_of_frame);
2242547cdfd21ee21e4ab9ca8692d6ef47c62ee7ea52Tong Shen
2243c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  // spill xmms
2244c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t offset = rest_of_frame;
2245c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  for (int i = spill_regs.size() - 1; i >= 0; --i) {
2246c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2247c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsXmmRegister()) {
2248c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      offset -= sizeof(double);
2249c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      movsd(Address(CpuRegister(RSP), offset), spill.AsXmmRegister());
2250dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.RelOffset(DWARFReg(spill.AsXmmRegister().AsFloatRegister()), offset);
2251c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2252c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  }
2253cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe
2254cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  DCHECK_EQ(4U, sizeof(StackReference<mirror::ArtMethod>));
2255c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov
2256cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  movl(Address(CpuRegister(RSP), 0), method_reg.AsX86_64().AsCpuRegister());
2257fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2258fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (size_t i = 0; i < entry_spills.size(); ++i) {
2259fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    ManagedRegisterSpill spill = entry_spills.at(i);
2260fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (spill.AsX86_64().IsCpuRegister()) {
2261fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (spill.getSize() == 8) {
2262dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movq(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()),
2263dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers             spill.AsX86_64().AsCpuRegister());
2264fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2265fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(spill.getSize(), 4);
2266dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movl(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsCpuRegister());
2267fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2268fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2269fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (spill.getSize() == 8) {
2270dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movsd(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister());
2271fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2272fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(spill.getSize(), 4);
2273dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movss(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister());
2274fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2275fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2276fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2277fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2278fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2279fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::RemoveFrame(size_t frame_size,
2280fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                            const std::vector<ManagedRegister>& spill_regs) {
2281fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(frame_size, kStackAlignment);
2282dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.RememberState();
2283c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int gpr_count = 0;
2284c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  // unspill xmms
2285c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t offset = static_cast<int64_t>(frame_size) - (spill_regs.size() * kFramePointerSize) - 2 * kFramePointerSize;
2286fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (size_t i = 0; i < spill_regs.size(); ++i) {
2287c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2288c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsXmmRegister()) {
2289c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      offset += sizeof(double);
2290c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      movsd(spill.AsXmmRegister(), Address(CpuRegister(RSP), offset));
2291dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.Restore(DWARFReg(spill.AsXmmRegister().AsFloatRegister()));
2292c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    } else {
2293c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      gpr_count++;
2294c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2295c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  }
2296dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  int adjust = static_cast<int>(frame_size) - (gpr_count * kFramePointerSize) - kFramePointerSize;
2297dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  addq(CpuRegister(RSP), Immediate(adjust));
2298dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(-adjust);
2299c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  for (size_t i = 0; i < spill_regs.size(); ++i) {
2300c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2301c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsCpuRegister()) {
2302c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      popq(spill.AsCpuRegister());
2303dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.AdjustCFAOffset(-static_cast<int>(kFramePointerSize));
2304dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.Restore(DWARFReg(spill.AsCpuRegister().AsRegister()));
2305c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2306fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2307fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  ret();
2308dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  // The CFI should be restored for any code that follows the exit block.
2309dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.RestoreState();
2310dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.DefCFAOffset(frame_size);
2311fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2312fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2313fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::IncreaseFrameSize(size_t adjust) {
2314fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(adjust, kStackAlignment);
23155408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate  addq(CpuRegister(RSP), Immediate(-static_cast<int64_t>(adjust)));
2316dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(adjust);
2317fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2318fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2319fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::DecreaseFrameSize(size_t adjust) {
2320fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(adjust, kStackAlignment);
2321dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  addq(CpuRegister(RSP), Immediate(adjust));
2322dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(-adjust);
2323fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2324fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2325fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) {
2326fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2327fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (src.IsNoRegister()) {
2328fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2329fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsCpuRegister()) {
2330fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2331fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(4u, size);
2332dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movl(Address(CpuRegister(RSP), offs), src.AsCpuRegister());
2333fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2334fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(8u, size);
2335dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movq(Address(CpuRegister(RSP), offs), src.AsCpuRegister());
2336fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2337fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsRegisterPair()) {
2338fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2339dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(Address(CpuRegister(RSP), offs), src.AsRegisterPairLow());
2340dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(Address(CpuRegister(RSP), FrameOffset(offs.Int32Value()+4)),
2341fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko         src.AsRegisterPairHigh());
2342fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsX87Register()) {
2343fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2344dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fstps(Address(CpuRegister(RSP), offs));
2345fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2346dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fstpl(Address(CpuRegister(RSP), offs));
2347fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2348fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2349fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(src.IsXmmRegister());
2350fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2351dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movss(Address(CpuRegister(RSP), offs), src.AsXmmRegister());
2352fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2353dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movsd(Address(CpuRegister(RSP), offs), src.AsXmmRegister());
2354fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2355fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2356fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2357fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2358fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
2359fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2360fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(src.IsCpuRegister());
2361cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  movl(Address(CpuRegister(RSP), dest), src.AsCpuRegister());
2362fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2363fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2364fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
2365fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2366fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(src.IsCpuRegister());
2367dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), dest), src.AsCpuRegister());
2368fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2369fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2370fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
2371dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                            ManagedRegister) {
2372dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(Address(CpuRegister(RSP), dest), Immediate(imm));  // TODO(64) movq?
2373fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2374fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2375dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
2376dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                               ManagedRegister) {
2377fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movl(Address::Absolute(dest, true), Immediate(imm));  // TODO(64) movq?
2378fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2379fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2380dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreStackOffsetToThread64(ThreadOffset<8> thr_offs,
2381dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                 FrameOffset fr_offs,
2382dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                 ManagedRegister mscratch) {
2383fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2384fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2385dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), fr_offs));
2386fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister());
2387fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2389dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreStackPointerToThread64(ThreadOffset<8> thr_offs) {
2390dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(Address::Absolute(thr_offs, true), CpuRegister(RSP));
2391fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2392fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2393fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreSpanning(FrameOffset /*dst*/, ManagedRegister /*src*/,
2394fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                 FrameOffset /*in_off*/, ManagedRegister /*scratch*/) {
2395fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  UNIMPLEMENTED(FATAL);  // this case only currently exists for ARM
2396fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2397fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2398fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) {
2399fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2400fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (dest.IsNoRegister()) {
2401fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2402fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsCpuRegister()) {
2403fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2404fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(4u, size);
2405dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movl(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2406fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2407fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(8u, size);
2408dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2409fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2410fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsRegisterPair()) {
2411fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2412dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(dest.AsRegisterPairLow(), Address(CpuRegister(RSP), src));
2413dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(dest.AsRegisterPairHigh(), Address(CpuRegister(RSP), FrameOffset(src.Int32Value()+4)));
2414fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsX87Register()) {
2415fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2416dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      flds(Address(CpuRegister(RSP), src));
2417fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2418dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fldl(Address(CpuRegister(RSP), src));
2419fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2420fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2421fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(dest.IsXmmRegister());
2422fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2423dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), src));
2424fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2425dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), src));
2426fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2427fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2428fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2429fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2430dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) {
2431fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (dest.IsNoRegister()) {
2433fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsCpuRegister()) {
2435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(4u, size);
2436dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    gs()->movl(dest.AsCpuRegister(), Address::Absolute(src, true));
2437fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsRegisterPair()) {
2438fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(8u, size);
2439fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    gs()->movq(dest.AsRegisterPairLow(), Address::Absolute(src, true));
2440fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsX87Register()) {
2441fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2442fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->flds(Address::Absolute(src, true));
2443fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2444fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->fldl(Address::Absolute(src, true));
2445fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2446fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2447fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(dest.IsXmmRegister());
2448fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2449fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->movss(dest.AsXmmRegister(), Address::Absolute(src, true));
2450fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2451fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->movsd(dest.AsXmmRegister(), Address::Absolute(src, true));
2452fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2453fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2455fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2456fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadRef(ManagedRegister mdest, FrameOffset  src) {
2457fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2458fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister());
2459dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2460fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2461fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2462fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base,
2463fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                           MemberOffset offs) {
2464fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2465fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
2466f889267adadd62c92d1d3726764598946a961c10Hiroshi Yamauchi  movl(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
2467b88f0b16dbaff09a140d2a62b66eca2736ff514bHiroshi Yamauchi  if (kPoisonHeapReferences) {
2468b88f0b16dbaff09a140d2a62b66eca2736ff514bHiroshi Yamauchi    negl(dest.AsCpuRegister());
2469b88f0b16dbaff09a140d2a62b66eca2736ff514bHiroshi Yamauchi  }
2470fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2471fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2472fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
2473fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                              Offset offs) {
2474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2475fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
2476fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
2477fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2478fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2479dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) {
2480fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister());
2482fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(dest.AsCpuRegister(), Address::Absolute(offs, true));
2483fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2484fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2485fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::SignExtend(ManagedRegister mreg, size_t size) {
2486fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister reg = mreg.AsX86_64();
2487fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(size == 1 || size == 2) << size;
2488fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(reg.IsCpuRegister()) << reg;
2489fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (size == 1) {
2490dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movsxb(reg.AsCpuRegister(), reg.AsCpuRegister());
2491fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2492fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    movsxw(reg.AsCpuRegister(), reg.AsCpuRegister());
2493fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2494fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2495fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2496fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ZeroExtend(ManagedRegister mreg, size_t size) {
2497fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister reg = mreg.AsX86_64();
2498fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(size == 1 || size == 2) << size;
2499fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(reg.IsCpuRegister()) << reg;
2500fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (size == 1) {
2501dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movzxb(reg.AsCpuRegister(), reg.AsCpuRegister());
2502fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2503fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    movzxw(reg.AsCpuRegister(), reg.AsCpuRegister());
2504fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2505fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2506fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2507fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
2508fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2509fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2510fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (!dest.Equals(src)) {
2511fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (dest.IsCpuRegister() && src.IsCpuRegister()) {
2512fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      movq(dest.AsCpuRegister(), src.AsCpuRegister());
2513fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else if (src.IsX87Register() && dest.IsXmmRegister()) {
2514fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      // Pass via stack and pop X87 register
2515dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      subl(CpuRegister(RSP), Immediate(16));
2516fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (size == 4) {
2517fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(src.AsX87Register(), ST0);
2518dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        fstps(Address(CpuRegister(RSP), 0));
2519dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0));
2520fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2521fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(src.AsX87Register(), ST0);
2522dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        fstpl(Address(CpuRegister(RSP), 0));
2523dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0));
2524fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2525dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      addq(CpuRegister(RSP), Immediate(16));
2526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2527fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      // TODO: x87, SSE
2528fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      UNIMPLEMENTED(FATAL) << ": Move " << dest << ", " << src;
2529fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2530fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2531fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2532fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2533fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::CopyRef(FrameOffset dest, FrameOffset src,
2534fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                           ManagedRegister mscratch) {
2535fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2536fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2537dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), src));
2538dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(Address(CpuRegister(RSP), dest), scratch.AsCpuRegister());
2539fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2540fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2541dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CopyRawPtrFromThread64(FrameOffset fr_offs,
2542dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                             ThreadOffset<8> thr_offs,
2543dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                             ManagedRegister mscratch) {
2544fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2545fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2546fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(scratch.AsCpuRegister(), Address::Absolute(thr_offs, true));
2547fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Store(fr_offs, scratch, 8);
2548fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2549fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2550dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CopyRawPtrToThread64(ThreadOffset<8> thr_offs,
2551dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                           FrameOffset fr_offs,
2552dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                           ManagedRegister mscratch) {
2553fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2554fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2555fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Load(scratch, fr_offs, 8);
2556fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister());
2557fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2558fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2559fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, FrameOffset src,
2560fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch,
2561fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        size_t size) {
2562fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2563fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (scratch.IsCpuRegister() && size == 8) {
2564fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, src, 4);
2565fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(dest, scratch, 4);
2566fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, FrameOffset(src.Int32Value() + 4), 4);
2567fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(FrameOffset(dest.Int32Value() + 4), scratch, 4);
2568fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2569fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, src, size);
2570fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(dest, scratch, size);
2571fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2572fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2573fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2574fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset /*dst*/, ManagedRegister /*src_base*/, Offset /*src_offset*/,
2575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister /*scratch*/, size_t /*size*/) {
2576fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  UNIMPLEMENTED(FATAL);
2577fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2578fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2579fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
2580fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister scratch, size_t size) {
2581fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsNoRegister());
2582fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2583dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  pushq(Address(CpuRegister(RSP), src));
2584fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(dest_base.AsX86_64().AsCpuRegister(), dest_offset));
2585fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2586fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2587fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
2588fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch, size_t size) {
2589dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2590fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2591dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(scratch, Address(CpuRegister(RSP), src_base));
2592fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(scratch, Address(scratch, src_offset));
2593dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), dest), scratch);
2594fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2595fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2596fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(ManagedRegister dest, Offset dest_offset,
2597fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister src, Offset src_offset,
2598fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister scratch, size_t size) {
2599fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2600fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsNoRegister());
2601fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Address(src.AsX86_64().AsCpuRegister(), src_offset));
2602fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(dest.AsX86_64().AsCpuRegister(), dest_offset));
2603fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2604fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2605fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
2606fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch, size_t size) {
2607dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2608fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2609fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(dest.Int32Value(), src.Int32Value());
2610dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(scratch, Address(CpuRegister(RSP), src));
2611fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Address(scratch, src_offset));
2612fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(scratch, dest_offset));
2613fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2614fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2615fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::MemoryBarrier(ManagedRegister) {
2616fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  mfence();
2617fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2618fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2619eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::CreateHandleScopeEntry(ManagedRegister mout_reg,
2620eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                   FrameOffset handle_scope_offset,
2621fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   ManagedRegister min_reg, bool null_allowed) {
2622fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister out_reg = mout_reg.AsX86_64();
2623fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister in_reg = min_reg.AsX86_64();
2624fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (in_reg.IsNoRegister()) {  // TODO(64): && null_allowed
2625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use out_reg as indicator of NULL
2626fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    in_reg = out_reg;
2627fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // TODO: movzwl
2628eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    movl(in_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2629fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2630fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(in_reg.IsCpuRegister());
2631fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(out_reg.IsCpuRegister());
2632fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  VerifyObject(in_reg, null_allowed);
2633fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (null_allowed) {
2634fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Label null_arg;
2635fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (!out_reg.Equals(in_reg)) {
2636fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
2637fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2638fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
2639fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    j(kZero, &null_arg);
2640eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2641fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Bind(&null_arg);
2642fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2643eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2644fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2645fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2646fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2647eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::CreateHandleScopeEntry(FrameOffset out_off,
2648eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                   FrameOffset handle_scope_offset,
2649fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   ManagedRegister mscratch,
2650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   bool null_allowed) {
2651fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2653fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (null_allowed) {
2654fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Label null_arg;
2655eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2656fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    testl(scratch.AsCpuRegister(), scratch.AsCpuRegister());
2657fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    j(kZero, &null_arg);
2658eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2659fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Bind(&null_arg);
2660fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2661eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2662fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2663fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Store(out_off, scratch, 8);
2664fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2665fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2666eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Given a handle scope entry, load the associated reference.
2667eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::LoadReferenceFromHandleScope(ManagedRegister mout_reg,
2668fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                         ManagedRegister min_reg) {
2669fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister out_reg = mout_reg.AsX86_64();
2670fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister in_reg = min_reg.AsX86_64();
2671fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(out_reg.IsCpuRegister());
2672fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(in_reg.IsCpuRegister());
2673fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Label null_arg;
2674fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (!out_reg.Equals(in_reg)) {
2675fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
2676fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2677fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
2678fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  j(kZero, &null_arg);
2679fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(out_reg.AsCpuRegister(), Address(in_reg.AsCpuRegister(), 0));
2680fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Bind(&null_arg);
2681fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2682fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2683fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
2684fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: not validating references
2685fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2686fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2687fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
2688fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: not validating references
2689fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2690fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2691fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Call(ManagedRegister mbase, Offset offset, ManagedRegister) {
2692fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister base = mbase.AsX86_64();
2693fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(base.IsCpuRegister());
2694fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  call(Address(base.AsCpuRegister(), offset.Int32Value()));
2695fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: place reference map on call
2696fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2697fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2698fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) {
2699dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2700cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  movl(scratch, Address(CpuRegister(RSP), base));
2701fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  call(Address(scratch, offset));
2702fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2703fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2704dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CallFromThread64(ThreadOffset<8> offset, ManagedRegister /*mscratch*/) {
2705fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->call(Address::Absolute(offset, true));
2706fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2707fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2708fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::GetCurrentThread(ManagedRegister tr) {
2709dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(tr.AsX86_64().AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true));
2710fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2711fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2712dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::GetCurrentThread(FrameOffset offset, ManagedRegister mscratch) {
2713fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2714dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(scratch.AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true));
2715dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), offset), scratch.AsCpuRegister());
2716fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2717fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2718dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Slowpath entered when Thread::Current()->_exception is non-null
2719dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass X86_64ExceptionSlowPath FINAL : public SlowPath {
2720dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers public:
2721dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  explicit X86_64ExceptionSlowPath(size_t stack_adjust) : stack_adjust_(stack_adjust) {}
2722dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  virtual void Emit(Assembler *sp_asm) OVERRIDE;
2723dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers private:
2724dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  const size_t stack_adjust_;
2725dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers};
2726dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2727fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ExceptionPoll(ManagedRegister /*scratch*/, size_t stack_adjust) {
2728dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  X86_64ExceptionSlowPath* slow = new X86_64ExceptionSlowPath(stack_adjust);
2729fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  buffer_.EnqueueSlowPath(slow);
2730dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->cmpl(Address::Absolute(Thread::ExceptionOffset<8>(), true), Immediate(0));
2731fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  j(kNotEqual, slow->Entry());
2732fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2733fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2734dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64ExceptionSlowPath::Emit(Assembler *sasm) {
2735fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64Assembler* sp_asm = down_cast<X86_64Assembler*>(sasm);
2736fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#define __ sp_asm->
2737fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  __ Bind(&entry_);
2738fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Note: the return value is dead
2739fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (stack_adjust_ != 0) {  // Fix up the frame.
2740fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    __ DecreaseFrameSize(stack_adjust_);
2741fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2742dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Pass exception as argument in RDI
2743dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  __ gs()->movq(CpuRegister(RDI), Address::Absolute(Thread::ExceptionOffset<8>(), true));
2744dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(8, pDeliverException), true));
2745fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // this call should never return
2746fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  __ int3();
2747fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#undef __
2748fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2749fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2750f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellvoid X86_64Assembler::AddConstantArea() {
2751f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  const std::vector<int32_t>& area = constant_area_.GetBuffer();
275239dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell  for (size_t i = 0, e = area.size(); i < e; i++) {
2753f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2754f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    EmitInt32(area[i]);
2755f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2756f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2757f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2758f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddInt32(int32_t v) {
275939dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell  for (size_t i = 0, e = buffer_.size(); i < e; i++) {
2760f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    if (v == buffer_[i]) {
2761f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell      return i * elem_size_;
2762f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    }
2763f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2764f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2765f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Didn't match anything.
2766f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int result = buffer_.size() * elem_size_;
2767f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v);
2768f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return result;
2769f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2770f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2771f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddInt64(int64_t v) {
2772f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int32_t v_low = v;
2773f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int32_t v_high = v >> 32;
2774f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  if (buffer_.size() > 1) {
2775f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    // Ensure we don't pass the end of the buffer.
277639dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell    for (size_t i = 0, e = buffer_.size() - 1; i < e; i++) {
277739dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell      if (v_low == buffer_[i] && v_high == buffer_[i + 1]) {
2778f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell        return i * elem_size_;
2779f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell      }
2780f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    }
2781f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2782f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2783f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Didn't match anything.
2784f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int result = buffer_.size() * elem_size_;
2785f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v_low);
2786f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v_high);
2787f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return result;
2788f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2789f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2790f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddDouble(double v) {
2791f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Treat the value as a 64-bit integer value.
2792f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return AddInt64(bit_cast<int64_t, double>(v));
2793f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2794f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2795f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddFloat(float v) {
2796f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Treat the value as a 32-bit integer value.
2797f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return AddInt32(bit_cast<int32_t, float>(v));
2798f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2799f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2800fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}  // namespace x86_64
2801fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}  // namespace art
2802