assembler_x86_64.cc revision 39dcf55a56da746e04f477f89e7b00ba1de03880
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
991fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fincstp() {
992fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
993fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
994fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
995fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
996fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
997fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
998fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ffree(const Immediate& index) {
999fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(index.value(), 7);
1000fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1001fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xDD);
1002fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC0 + index.value());
1003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1004fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1005fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1006fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fsin() {
1007fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1008fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1009fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFE);
1010fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1011fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1012fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1013fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fcos() {
1014fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1015fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1016fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1017fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1019fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1020fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::fptan() {
1021fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1022fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD9);
1023fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF2);
1024fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1025fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
102624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fucompp() {
102724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
102824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xDA);
102924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xE9);
103024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
103124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
103224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
103324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendellvoid X86_64Assembler::fprem() {
103424f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
103524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xD9);
103624f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell  EmitUint8(0xF8);
103724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell}
103824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell
1039fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1040dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xchgl(CpuRegister dst, CpuRegister src) {
1041fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1042851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // There is a short version for rax.
1043851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't
1044851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // work.
1045851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool src_rax = src.AsRegister() == RAX;
1046851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool dst_rax = dst.AsRegister() == RAX;
1047851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  if (src_rax || dst_rax) {
1048851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOptionalRex32(src_rax ? dst : src);
1049851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits()));
1050851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    return;
1051851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1052851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1053851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // General case.
1054851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitOptionalRex32(src, dst);
1055fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x87);
1056851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
1057fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1058fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1059ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1060ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffrayvoid X86_64Assembler::xchgq(CpuRegister dst, CpuRegister src) {
1061ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1062851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // There is a short version for rax.
1063851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't
1064851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // work.
1065851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool src_rax = src.AsRegister() == RAX;
1066851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  const bool dst_rax = dst.AsRegister() == RAX;
1067851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  if (src_rax || dst_rax) {
1068851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // If src == target, emit a nop instead.
1069851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    if (src_rax && dst_rax) {
1070851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitUint8(0x90);
1071851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    } else {
1072851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitRex64(src_rax ? dst : src);
1073851df20225593b10e698a760ac3cd5243620700bAndreas Gampe      EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits()));
1074851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    }
1075851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    return;
1076851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1077851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1078851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // General case.
1079851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRex64(src, dst);
1080ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray  EmitUint8(0x87);
1081851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
1082ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray}
1083ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1084ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray
1085dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xchgl(CpuRegister reg, const Address& address) {
1086fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1087dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1088fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x87);
1089dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1090fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1091fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1092fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
10933c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffrayvoid X86_64Assembler::cmpw(const Address& address, const Immediate& imm) {
10943c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
10953c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitOptionalRex32(address);
10963c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitUint8(0x66);
10973c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  EmitComplex(7, address, imm);
10983c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray}
10993c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
11003c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
1101dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg, const Immediate& imm) {
1102fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1103dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1104fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(7, Operand(reg), imm);
1105fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1106fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1107fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1108dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg0, CpuRegister reg1) {
1109fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1110dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg0, reg1);
1111fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x3B);
1112dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg0.LowBits(), Operand(reg1));
1113fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1114fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1115fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1116dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpl(CpuRegister reg, const Address& address) {
1117fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1118dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1119fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x3B);
1120dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1121fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1122fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1123fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1124d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpl(const Address& address, CpuRegister reg) {
1125d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1126d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex32(reg, address);
1127d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x39);
1128d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOperand(reg.LowBits(), address);
1129d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1130d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1131d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1132d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpl(const Address& address, const Immediate& imm) {
1133d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1134d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex32(address);
1135d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitComplex(7, address, imm);
1136d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1137d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1138d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
11395a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::cmpq(CpuRegister reg0, CpuRegister reg1) {
11405a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
11415a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(reg0, reg1);
11425a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x3B);
11435a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitOperand(reg0.LowBits(), Operand(reg1));
11445a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
11455a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
11465a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
114796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::cmpq(CpuRegister reg, const Immediate& imm) {
114896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
114996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  CHECK(imm.is_int32());  // cmpq only supports 32b immediate.
115096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(reg);
115196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitComplex(7, Operand(reg), imm);
115296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
115396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
115496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
115596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::cmpq(CpuRegister reg, const Address& address) {
115696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
115796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(reg);
115896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x3B);
115996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
116096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
116196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
116296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
1163d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cmpq(const Address& address, const Immediate& imm) {
1164d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  CHECK(imm.is_int32());  // cmpq only supports 32b immediate.
1165d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1166d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(address);
1167d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitComplex(7, address, imm);
1168d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1169d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1170d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1171dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister dst, CpuRegister src) {
1172fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1173dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1174fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x03);
1175dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(dst.LowBits(), src.LowBits());
1176fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1177fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1178fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1179dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister reg, const Address& address) {
1180fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1181dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1182fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x03);
1183dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1184fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1185fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1186fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1187dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::testl(CpuRegister reg1, CpuRegister reg2) {
1188fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1189dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg1, reg2);
1190fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x85);
1191dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(reg1.LowBits(), reg2.LowBits());
1192fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1193fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1194fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1195cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravlevoid X86_64Assembler::testl(CpuRegister reg, const Address& address) {
1196cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1197cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitOptionalRex32(reg, address);
1198cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitUint8(0x85);
1199cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle  EmitOperand(reg.LowBits(), address);
1200cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle}
1201cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle
1202cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle
1203dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::testl(CpuRegister reg, const Immediate& immediate) {
1204fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1205fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // For registers that have a byte variant (RAX, RBX, RCX, and RDX)
1206dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // we only test the byte CpuRegister to keep the encoding short.
1207dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (immediate.is_uint8() && reg.AsRegister() < 4) {
1208fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use zero-extended 8-bit immediate.
1209dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    if (reg.AsRegister() == RAX) {
1210fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xA8);
1211fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1212fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xF6);
1213dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      EmitUint8(0xC0 + reg.AsRegister());
1214fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1215fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(immediate.value() & 0xFF);
1216dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  } else if (reg.AsRegister() == RAX) {
1217fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use short form if the destination is RAX.
1218fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xA9);
1219fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
1220fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1221dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitOptionalRex32(reg);
1222fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xF7);
1223fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(0, Operand(reg));
1224fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
1225fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1226fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1227fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1228fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1229d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::testq(CpuRegister reg1, CpuRegister reg2) {
1230d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1231d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(reg1, reg2);
1232d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x85);
1233d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRegisterOperand(reg1.LowBits(), reg2.LowBits());
1234d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1235d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1236d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1237f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffrayvoid X86_64Assembler::testq(CpuRegister reg, const Address& address) {
1238f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1239f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitRex64(reg);
1240f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitUint8(0x85);
1241f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
1242f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray}
1243f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1244f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1245dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::andl(CpuRegister dst, CpuRegister src) {
1246fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1247dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1248fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x23);
1249dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1250fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1251fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1252fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
12539574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::andl(CpuRegister reg, const Address& address) {
12549574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12559574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
12569574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x23);
12579574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
12589574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
12599574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
12609574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1261dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::andl(CpuRegister dst, const Immediate& imm) {
1262fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1263dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
1264fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(4, Operand(dst), imm);
1265fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1266fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1267fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1268412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffrayvoid X86_64Assembler::andq(CpuRegister reg, const Immediate& imm) {
1269412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1270412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  CHECK(imm.is_int32());  // andq only supports 32b immediate.
1271412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitRex64(reg);
1272412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitComplex(4, Operand(reg), imm);
1273412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray}
1274412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
1275412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
12769574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::andq(CpuRegister dst, CpuRegister src) {
12779574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12789574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitRex64(dst, src);
12799574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x23);
12809574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
12819574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
12829574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
12839574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1284dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::orl(CpuRegister dst, CpuRegister src) {
1285fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1286dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1287fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0B);
1288dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1289fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1290fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1291fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
12929574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::orl(CpuRegister reg, const Address& address) {
12939574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
12949574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
12959574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x0B);
12969574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
12979574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
12989574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
12999574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1300dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::orl(CpuRegister dst, const Immediate& imm) {
1301fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1302dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst);
1303fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(1, Operand(dst), imm);
1304fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1305fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1306fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
13073f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendellvoid X86_64Assembler::orq(CpuRegister dst, const Immediate& imm) {
13083f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13093f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  CHECK(imm.is_int32());  // orq only supports 32b immediate.
13103f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitRex64(dst);
13113f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitComplex(1, Operand(dst), imm);
13123f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell}
13133f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
13143f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
13159574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::orq(CpuRegister dst, CpuRegister src) {
13169574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13179574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitRex64(dst, src);
13189574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x0B);
13199574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
13209574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13219574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13229574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1323dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::xorl(CpuRegister dst, CpuRegister src) {
1324fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1325dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1326fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x33);
1327dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1328fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1329fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
13305a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
13319574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::xorl(CpuRegister reg, const Address& address) {
13329574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13339574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(reg, address);
13349574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitUint8(0x33);
13359574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOperand(reg.LowBits(), address);
13369574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13379574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13389574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13399574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffrayvoid X86_64Assembler::xorl(CpuRegister dst, const Immediate& imm) {
13409574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13419574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitOptionalRex32(dst);
13429574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray  EmitComplex(6, Operand(dst), imm);
13439574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray}
13449574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
13459574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray
1346412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffrayvoid X86_64Assembler::xorq(CpuRegister dst, CpuRegister src) {
1347412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1348412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitRex64(dst, src);
1349412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitUint8(0x33);
1350412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  EmitOperand(dst.LowBits(), Operand(src));
1351412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray}
1352412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
1353412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray
13545a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::xorq(CpuRegister dst, const Immediate& imm) {
13555a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
13565a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // xorq only supports 32b immediate.
13575a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(dst);
13585a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitComplex(6, Operand(dst), imm);
13595a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
13605a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1361dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#if 0
1362dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::rex(bool force, bool w, Register* r, Register* x, Register* b) {
1363fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // REX.WRXB
1364fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // W - 64-bit operand
1365fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // R - MODRM.reg
1366fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // X - SIB.index
1367fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // B - MODRM.rm/SIB.base
1368dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = force ? 0x40 : 0;
1369dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
1370fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x48;  // REX.W000
1371fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1372dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (r != nullptr && *r >= Register::R8 && *r < Register::kNumberOfCpuRegisters) {
1373fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x44;  // REX.0R00
1374dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *r = static_cast<Register>(*r - 8);
1375fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1376dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (x != nullptr && *x >= Register::R8 && *x < Register::kNumberOfCpuRegisters) {
1377dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x42;  // REX.00X0
1378dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *x = static_cast<Register>(*x - 8);
1379dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1380dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (b != nullptr && *b >= Register::R8 && *b < Register::kNumberOfCpuRegisters) {
1381fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    rex |= 0x41;  // REX.000B
1382dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *b = static_cast<Register>(*b - 8);
1383fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1384fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (rex != 0) {
1385fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(rex);
1386fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1387fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1389dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::rex_reg_mem(bool force, bool w, Register* dst, const Address& mem) {
1390dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // REX.WRXB
1391dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // W - 64-bit operand
1392dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // R - MODRM.reg
1393dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // X - SIB.index
1394dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // B - MODRM.rm/SIB.base
1395dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = mem->rex();
1396dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (force) {
1397dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x40;  // REX.0000
1398dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1399dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
1400dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x48;  // REX.W000
1401dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1402dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (dst != nullptr && *dst >= Register::R8 && *dst < Register::kNumberOfCpuRegisters) {
1403dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x44;  // REX.0R00
1404dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    *dst = static_cast<Register>(*dst - 8);
1405dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1406dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (rex != 0) {
1407dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitUint8(rex);
1408dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1409dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
1410dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1411dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid rex_mem_reg(bool force, bool w, Address* mem, Register* src);
1412dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#endif
1413dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1414dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(CpuRegister reg, const Immediate& imm) {
1415fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1416dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1417fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, Operand(reg), imm);
1418fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1419fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1420fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1421dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addq(CpuRegister reg, const Immediate& imm) {
1422fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14235a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // addq only supports 32b immediate.
1424dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRex64(reg);
1425fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, Operand(reg), imm);
1426fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1427fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1428fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
142996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::addq(CpuRegister dst, const Address& address) {
143096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
143196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(dst);
143296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x03);
143396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(dst.LowBits(), address);
143496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
143596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
143696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
14375a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::addq(CpuRegister dst, CpuRegister src) {
14385a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14395a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // 0x01 is addq r/m64 <- r/m64 + r64, with op1 in r/m and op2 in reg: so reverse EmitRex64
14405a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(src, dst);
14415a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x01);
14425a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRegisterOperand(src.LowBits(), dst.LowBits());
14435a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
14445a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14455a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1446dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::addl(const Address& address, CpuRegister reg) {
1447fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1448dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1449fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x01);
1450dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1451fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1452fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1453fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::addl(const Address& address, const Immediate& imm) {
1455fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1456dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1457fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(0, address, imm);
1458fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1459fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1460fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1461dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister dst, CpuRegister src) {
1462fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1463dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1464fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2B);
1465dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1467fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1468fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1469dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister reg, const Immediate& imm) {
1470fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1471dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1472fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitComplex(5, Operand(reg), imm);
1473fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1475fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
14765a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::subq(CpuRegister reg, const Immediate& imm) {
14775a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14785a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  CHECK(imm.is_int32());  // subq only supports 32b immediate.
14795a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(reg);
14805a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitComplex(5, Operand(reg), imm);
14815a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
14825a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14835a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14845a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::subq(CpuRegister dst, CpuRegister src) {
14855a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
14865a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRex64(dst, src);
14875a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x2B);
14885a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitRegisterOperand(dst.LowBits(), src.LowBits());
14895a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
14905a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
14915a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
149296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayvoid X86_64Assembler::subq(CpuRegister reg, const Address& address) {
149396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
149496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitRex64(reg);
149596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitUint8(0x2B);
149696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  EmitOperand(reg.LowBits() & 7, address);
149796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray}
149896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
149996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
1500dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::subl(CpuRegister reg, const Address& address) {
1501fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1502dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1503fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x2B);
1504dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1505fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1506fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1507fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1508fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::cdq() {
1509fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1510fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x99);
1511fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1512fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1513fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1514d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::cqo() {
1515d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1516d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64();
1517d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0x99);
1518d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1519d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1520d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1521dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::idivl(CpuRegister reg) {
1522fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1523dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1524fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1525dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xF8 | reg.LowBits());
1526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1527fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1528fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1529d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::idivq(CpuRegister reg) {
1530d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1531d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitRex64(reg);
1532d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0xF7);
1533d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(0xF8 | reg.LowBits());
1534d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
1535d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1536d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
1537dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister dst, CpuRegister src) {
1538fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1539dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(dst, src);
1540fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1541fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAF);
1542dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(dst.LowBits(), Operand(src));
1543fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1544fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1545dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg, const Immediate& imm) {
1546fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1547851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  CHECK(imm.is_int32());  // imull only supports 32b immediate.
1548851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1549b5de00f1c8f53e6552f1778702673c6274a98bb3Nicolas Geoffray  EmitOptionalRex32(reg, reg);
1550851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1551851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // See whether imm can be represented as a sign-extended 8bit value.
1552851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  int32_t v32 = static_cast<int32_t>(imm.value());
1553ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  if (IsInt<8>(v32)) {
1554851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Sign-extension works.
1555851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x6B);
1556851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOperand(reg.LowBits(), Operand(reg));
1557851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(static_cast<uint8_t>(v32 & 0xFF));
1558851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
1559851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Not representable, use full immediate.
1560851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x69);
1561851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOperand(reg.LowBits(), Operand(reg));
1562851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitImmediate(imm);
1563851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
1564fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1565fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1566fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1567dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg, const Address& address) {
1568fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1569dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg, address);
1570fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1571fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAF);
1572dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1573fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1574fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
157634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister dst, CpuRegister src) {
157734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
157834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRex64(dst, src);
157934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0x0F);
158034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0xAF);
158134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRegisterOperand(dst.LowBits(), src.LowBits());
158234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
158334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
158434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
158534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister reg, const Immediate& imm) {
15863f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  imulq(reg, reg, imm);
15873f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell}
15883f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell
15893f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendellvoid X86_64Assembler::imulq(CpuRegister dst, CpuRegister reg, const Immediate& imm) {
159034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
159134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  CHECK(imm.is_int32());  // imulq only supports 32b immediate.
1592851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
15933f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell  EmitRex64(dst, reg);
1594851df20225593b10e698a760ac3cd5243620700bAndreas Gampe
1595851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  // See whether imm can be represented as a sign-extended 8bit value.
1596851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  int64_t v64 = imm.value();
1597ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  if (IsInt<8>(v64)) {
1598851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Sign-extension works.
1599851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x6B);
16003f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell    EmitOperand(dst.LowBits(), Operand(reg));
1601851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(static_cast<uint8_t>(v64 & 0xFF));
1602851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
1603851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    // Not representable, use full immediate.
1604851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitUint8(0x69);
16053f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell    EmitOperand(dst.LowBits(), Operand(reg));
1606851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitImmediate(imm);
1607851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  }
160834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
160934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
161034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravlevoid X86_64Assembler::imulq(CpuRegister reg, const Address& address) {
161134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
161234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitRex64(reg, address);
161334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0x0F);
161434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitUint8(0xAF);
161534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle  EmitOperand(reg.LowBits(), address);
161634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle}
161734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
161834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle
1619dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::imull(CpuRegister reg) {
1620fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1621dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1622fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1623fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, Operand(reg));
1624fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1626fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
16270f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchezvoid X86_64Assembler::imulq(CpuRegister reg) {
16280f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
16290f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitRex64(reg);
16300f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitUint8(0xF7);
16310f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez  EmitOperand(5, Operand(reg));
16320f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez}
16330f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez
16340f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez
1635fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::imull(const Address& address) {
1636fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1637dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1638fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1639fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(5, address);
1640fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1641fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1642fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1643dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::mull(CpuRegister reg) {
1644fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1645dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1646fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1647fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, Operand(reg));
1648fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1649fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1651fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mull(const Address& address) {
1652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1653dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1654fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1655fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, address);
1656fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1657fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1658fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1659dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shll(CpuRegister reg, const Immediate& imm) {
16601a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 4, reg, imm);
1661fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1662fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1663fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
16649aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shlq(CpuRegister reg, const Immediate& imm) {
16659aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 4, reg, imm);
16669aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
16679aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
16689aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
1669dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shll(CpuRegister operand, CpuRegister shifter) {
16709aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 4, operand, shifter);
16719aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
16729aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
16739aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
16749aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shlq(CpuRegister operand, CpuRegister shifter) {
16759aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 4, operand, shifter);
1676fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1677fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1678fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1679dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shrl(CpuRegister reg, const Immediate& imm) {
16801a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 5, reg, imm);
16811a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray}
16821a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray
16831a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray
16841a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffrayvoid X86_64Assembler::shrq(CpuRegister reg, const Immediate& imm) {
16851a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(true, 5, reg, imm);
1686fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1687fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1688fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1689dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::shrl(CpuRegister operand, CpuRegister shifter) {
16909aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 5, operand, shifter);
16919aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
16929aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
16939aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
16949aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::shrq(CpuRegister operand, CpuRegister shifter) {
16959aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 5, operand, shifter);
1696fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1697fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1698fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1699dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::sarl(CpuRegister reg, const Immediate& imm) {
17001a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  EmitGenericShift(false, 7, reg, imm);
1701fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1702fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1703fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1704dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::sarl(CpuRegister operand, CpuRegister shifter) {
17059aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(false, 7, operand, shifter);
17069aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
17079aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17089aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17099aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::sarq(CpuRegister reg, const Immediate& imm) {
17109aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 7, reg, imm);
17119aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle}
17129aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17139aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle
17149aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::sarq(CpuRegister operand, CpuRegister shifter) {
17159aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  EmitGenericShift(true, 7, operand, shifter);
1716fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1717fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1718fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1719dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::negl(CpuRegister reg) {
1720fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1721dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1722fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1723fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(3, Operand(reg));
1724fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1725fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1726705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
17272e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillainvoid X86_64Assembler::negq(CpuRegister reg) {
17282e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
17292e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitRex64(reg);
17302e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitUint8(0xF7);
17312e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain  EmitOperand(3, Operand(reg));
17322e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain}
17332e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain
1734fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1735dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::notl(CpuRegister reg) {
1736fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1737dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1738fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF7);
1739dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitUint8(0xD0 | reg.LowBits());
1740fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1741fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1742fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1743705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillainvoid X86_64Assembler::notq(CpuRegister reg) {
1744705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1745705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitRex64(reg);
1746705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitUint8(0xF7);
1747705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain  EmitOperand(2, Operand(reg));
1748705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain}
1749705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
1750705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain
1751fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::enter(const Immediate& imm) {
1752fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1753fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC8);
1754ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe  CHECK(imm.is_uint16()) << imm.value();
1755fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
1756fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8((imm.value() >> 8) & 0xFF);
1757fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x00);
1758fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1759fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1760fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1761fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::leave() {
1762fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1763fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC9);
1764fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1765fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1766fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1767fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ret() {
1768fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1769fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC3);
1770fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1771fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1772fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1773fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ret(const Immediate& imm) {
1774fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1775fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xC2);
1776fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_uint16());
1777fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(imm.value() & 0xFF);
1778fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8((imm.value() >> 8) & 0xFF);
1779fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1780fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1781fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1782fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1783fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::nop() {
1784fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1785fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x90);
1786fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1787fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1788fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1789fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::int3() {
1790fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1791fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xCC);
1792fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1793fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1794fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1795fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::hlt() {
1796fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1797fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF4);
1798fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1799fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1800fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1801fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::j(Condition condition, Label* label) {
1802fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1803fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
1804fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kShortSize = 2;
1805fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kLongSize = 6;
1806fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
1807fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
1808ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe    if (IsInt<8>(offset - kShortSize)) {
1809fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x70 + condition);
1810fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8((offset - kShortSize) & 0xFF);
1811fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1812fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x0F);
1813fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0x80 + condition);
1814fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitInt32(offset - kLongSize);
1815fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1816fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1817fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x0F);
1818fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x80 + condition);
1819fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
1820fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1821fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1822fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1823fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1824dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::jmp(CpuRegister reg) {
1825fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1826dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(reg);
1827fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1828dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitRegisterOperand(4, reg.LowBits());
1829fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1830fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1831fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::jmp(const Address& address) {
1832fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1833dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex32(address);
1834fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xFF);
1835fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(4, address);
1836fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1837fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1838fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::jmp(Label* label) {
1839fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1840fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
1841fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kShortSize = 2;
1842fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    static const int kLongSize = 5;
1843fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
1844fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
1845ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe    if (IsInt<8>(offset - kShortSize)) {
1846fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xEB);
1847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8((offset - kShortSize) & 0xFF);
1848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
1849fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitUint8(0xE9);
1850fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      EmitInt32(offset - kLongSize);
1851fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1852fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
1853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xE9);
1854fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
1855fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1856fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1857fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1858fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1859fca82208f7128fcda09b6a4743199308332558a2Dmitry PetrochenkoX86_64Assembler* X86_64Assembler::lock() {
1860fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1861fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF0);
1862fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return this;
1863fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1864fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1865fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1866dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::cmpxchgl(const Address& address, CpuRegister reg) {
1867fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
186858d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitOptionalRex32(reg, address);
186958d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitUint8(0x0F);
187058d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitUint8(0xB1);
187158d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitOperand(reg.LowBits(), address);
187258d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell}
187358d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
187458d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
187558d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendellvoid X86_64Assembler::cmpxchgq(const Address& address, CpuRegister reg) {
187658d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
187758d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell  EmitRex64(reg, address);
1878fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1879fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xB1);
1880dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOperand(reg.LowBits(), address);
1881fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1882fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
188358d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell
1884fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::mfence() {
1885fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1886fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x0F);
1887fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xAE);
1888fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xF0);
1889fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1890fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
18915a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1892fca82208f7128fcda09b6a4743199308332558a2Dmitry PetrochenkoX86_64Assembler* X86_64Assembler::gs() {
18935a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // TODO: gs is a prefix and not an instruction
1894fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1895fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0x65);
1896fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  return this;
1897fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1898fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
18995a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1900dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::AddImmediate(CpuRegister reg, const Immediate& imm) {
1901fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int value = imm.value();
1902dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (value != 0) {
1903dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    if (value > 0) {
1904fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      addl(reg, imm);
1905dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    } else {
1906fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      subl(reg, Immediate(value));
1907fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
1908fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1909fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1910fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1911fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
19125a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampevoid X86_64Assembler::setcc(Condition condition, CpuRegister dst) {
19135a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
19145a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  // RSP, RBP, RDI, RSI need rex prefix (else the pattern encodes ah/bh/ch/dh).
19155a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (dst.NeedsRex() || dst.AsRegister() > 3) {
19165a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitOptionalRex(true, false, false, false, dst.NeedsRex());
19175a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
19185a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x0F);
19195a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0x90 + condition);
19205a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  EmitUint8(0xC0 + dst.LowBits());
19215a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe}
19225a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
192371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::bswapl(CpuRegister dst) {
192471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
192571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, false, false, false, dst.NeedsRex());
192671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
192771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0xC8 + dst.LowBits());
192871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
192971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
193071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid X86_64Assembler::bswapq(CpuRegister dst) {
193171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
193271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitOptionalRex(false, true, false, false, dst.NeedsRex());
193371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0x0F);
193471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  EmitUint8(0xC8 + dst.LowBits());
193571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}
193671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
19375a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe
1938fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
1939fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: Need to have a code constants table.
1940fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int64_t constant = bit_cast<int64_t, double>(value);
1941fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Immediate(High32Bits(constant)));
1942fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Immediate(Low32Bits(constant)));
1943dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movsd(dst, Address(CpuRegister(RSP), 0));
194413735955f39b3b304c37d2b2840663c131262c18Ian Rogers  addq(CpuRegister(RSP), Immediate(2 * sizeof(intptr_t)));
1945fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1946fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1947fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1948fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Align(int alignment, int offset) {
1949fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(IsPowerOfTwo(alignment));
1950fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit nop instruction until the real position is aligned.
1951fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) {
1952fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    nop();
1953fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1954fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1955fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1956fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1957fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Bind(Label* label) {
1958fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int bound = buffer_.Size();
1959fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(!label->IsBound());  // Labels can only be bound once.
1960fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  while (label->IsLinked()) {
1961fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int position = label->LinkPosition();
1962fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int next = buffer_.Load<int32_t>(position);
1963fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    buffer_.Store<int32_t>(position, bound - (position + 4));
1964fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    label->position_ = next;
1965fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1966fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  label->BindTo(bound);
1967fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1968fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1969fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1970dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOperand(uint8_t reg_or_opcode, const Operand& operand) {
1971fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GE(reg_or_opcode, 0);
1972fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(reg_or_opcode, 8);
1973fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  const int length = operand.length_;
1974fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GT(length, 0);
1975fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit the ModRM byte updated with the given reg value.
1976fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(operand.encoding_[0] & 0x38, 0);
1977fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(operand.encoding_[0] + (reg_or_opcode << 3));
1978fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Emit the rest of the encoded operand.
1979fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (int i = 1; i < length; i++) {
1980fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(operand.encoding_[i]);
1981fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
1982f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  AssemblerFixup* fixup = operand.GetFixup();
1983f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  if (fixup != nullptr) {
1984f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    EmitFixup(fixup);
1985f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
1986fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1987fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1988fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1989fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitImmediate(const Immediate& imm) {
19905a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  if (imm.is_int32()) {
19915a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt32(static_cast<int32_t>(imm.value()));
19925a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  } else {
19935a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe    EmitInt64(imm.value());
19945a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe  }
1995fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
1996fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1997fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1998dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitComplex(uint8_t reg_or_opcode,
1999dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                  const Operand& operand,
2000dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                  const Immediate& immediate) {
2001fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_GE(reg_or_opcode, 0);
2002fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_LT(reg_or_opcode, 8);
2003fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (immediate.is_int8()) {
2004fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use sign-extended 8-bit immediate.
2005fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x83);
2006fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, operand);
2007fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(immediate.value() & 0xFF);
2008dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  } else if (operand.IsRegister(CpuRegister(RAX))) {
2009fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use short form if the destination is eax.
2010fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x05 + (reg_or_opcode << 3));
2011fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
2012fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2013fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0x81);
2014fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, operand);
2015fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitImmediate(immediate);
2016fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2017fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2018fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2019fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2020fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitLabel(Label* label, int instruction_size) {
2021fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (label->IsBound()) {
2022fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    int offset = label->Position() - buffer_.Size();
2023fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_LE(offset, 0);
2024fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitInt32(offset - instruction_size);
2025fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2026fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitLabelLink(label);
2027fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2028fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2029fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2030fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2031fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::EmitLabelLink(Label* label) {
2032fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(!label->IsBound());
2033fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int position = buffer_.Size();
2034fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitInt32(label->position_);
2035fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  label->LinkTo(position);
2036fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2037fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2038fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
20391a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffrayvoid X86_64Assembler::EmitGenericShift(bool wide,
20401a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       int reg_or_opcode,
20411a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister reg,
20421a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       const Immediate& imm) {
2043fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2044fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(imm.is_int8());
20451a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  if (wide) {
20461a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray    EmitRex64(reg);
2047851df20225593b10e698a760ac3cd5243620700bAndreas Gampe  } else {
2048851df20225593b10e698a760ac3cd5243620700bAndreas Gampe    EmitOptionalRex32(reg);
20491a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray  }
2050fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (imm.value() == 1) {
2051fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xD1);
2052fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, Operand(reg));
2053fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2054fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(0xC1);
2055fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitOperand(reg_or_opcode, Operand(reg));
2056fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    EmitUint8(imm.value() & 0xFF);
2057fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2058fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2059fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2060fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
20619aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravlevoid X86_64Assembler::EmitGenericShift(bool wide,
20629aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle                                       int reg_or_opcode,
20631a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister operand,
20641a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray                                       CpuRegister shifter) {
2065fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2066dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CHECK_EQ(shifter.AsRegister(), RCX);
20679aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  if (wide) {
20689aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle    EmitRex64(operand);
20699aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  } else {
20709aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle    EmitOptionalRex32(operand);
20719aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle  }
2072fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitUint8(0xD3);
2073fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  EmitOperand(reg_or_opcode, Operand(operand));
2074fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2075fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2076dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) {
2077dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // REX.WRXB
2078dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // W - 64-bit operand
2079dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // R - MODRM.reg
2080dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // X - SIB.index
2081dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // B - MODRM.rm/SIB.base
2082dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint8_t rex = force ? 0x40 : 0;
2083dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (w) {
2084dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x48;  // REX.W000
2085dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2086dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (r) {
2087dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x44;  // REX.0R00
2088dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2089dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (x) {
2090dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x42;  // REX.00X0
2091dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2092dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (b) {
2093dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    rex |= 0x41;  // REX.000B
2094dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2095dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (rex != 0) {
2096dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    EmitUint8(rex);
2097dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
2098dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2099dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2100dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister reg) {
2101fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov  EmitOptionalRex(false, false, false, false, reg.NeedsRex());
2102dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2103dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2104dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, CpuRegister src) {
2105dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2106dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2107dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2108dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, XmmRegister src) {
2109dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2110dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2111dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2112dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, XmmRegister src) {
2113dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2114dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2115dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2116dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, CpuRegister src) {
2117dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex());
2118dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2119dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2120dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(const Operand& operand) {
2121790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2122790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2123790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2124790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2125dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2126dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2127dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(CpuRegister dst, const Operand& operand) {
2128790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2129790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2130790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2131790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2132790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2133790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2134790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2135dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2136dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2137dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalRex32(XmmRegister dst, const Operand& operand) {
2138790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = operand.rex();
2139790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2140790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2141790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2142790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2143790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2144790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2145dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2146dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2147d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::EmitRex64() {
2148d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitOptionalRex(false, true, false, false, false);
2149d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
2150d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
2151dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister reg) {
2152fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov  EmitOptionalRex(false, true, false, false, reg.NeedsRex());
2153dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2154fba52f1b4bf753790c1d98265c4b0fabb54c7536Vladimir Kostyukov
2155d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravlevoid X86_64Assembler::EmitRex64(const Operand& operand) {
2156d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  uint8_t rex = operand.rex();
2157d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  rex |= 0x48;  // REX.W000
2158d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle  EmitUint8(rex);
2159d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle}
2160d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle
2161dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister dst, CpuRegister src) {
2162dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2163dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2164dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2165102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffrayvoid X86_64Assembler::EmitRex64(XmmRegister dst, CpuRegister src) {
2166102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2167102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray}
2168102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray
2169624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainvoid X86_64Assembler::EmitRex64(CpuRegister dst, XmmRegister src) {
2170624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain  EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex());
2171624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain}
2172624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain
2173dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitRex64(CpuRegister dst, const Operand& operand) {
2174790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  uint8_t rex = 0x48 | operand.rex();  // REX.W000
2175790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2176790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2177790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2178790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2179790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2180790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2181dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2182dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2183dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, CpuRegister src) {
2184d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // For src, SPL, BPL, SIL, DIL need the rex prefix.
2185d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  bool force = src.AsRegister() > 3;
2186d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  EmitOptionalRex(force, false, dst.NeedsRex(), false, src.NeedsRex());
2187dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2188dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2189dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, const Operand& operand) {
2190d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  uint8_t rex = operand.rex();
2191d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  // For dst, SPL, BPL, SIL, DIL need the rex prefix.
2192d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  bool force = dst.AsRegister() > 3;
2193d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  if (force) {
2194d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu    rex |= 0x40;  // REX.0000
2195d23840d3ed900c6072d71e6599b3568b68de6b7cChao-ying Fu  }
2196790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (dst.NeedsRex()) {
2197790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    rex |= 0x44;  // REX.0R00
2198790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2199790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  if (rex != 0) {
2200790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    EmitUint8(rex);
2201790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  }
2202dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
2203dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2204dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckystatic dwarf::Reg DWARFReg(Register reg) {
2205dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  return dwarf::Reg::X86_64Core(static_cast<int>(reg));
2206dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}
2207dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckystatic dwarf::Reg DWARFReg(FloatRegister reg) {
2208dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  return dwarf::Reg::X86_64Fp(static_cast<int>(reg));
2209dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}
2210dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
2211790a6b7312979513710c366b411ba6791ddf78c2Ian Rogersconstexpr size_t kFramePointerSize = 8;
2212790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers
2213fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
2214790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                                 const std::vector<ManagedRegister>& spill_regs,
2215790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                                 const ManagedRegisterEntrySpills& entry_spills) {
22168c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky  DCHECK_EQ(buffer_.Size(), 0U);  // Nothing emitted yet.
2217dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.SetCurrentCFAOffset(8);  // Return address on stack.
2218fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(frame_size, kStackAlignment);
2219c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int gpr_count = 0;
2220fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (int i = spill_regs.size() - 1; i >= 0; --i) {
2221c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2222c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsCpuRegister()) {
2223c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      pushq(spill.AsCpuRegister());
2224c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      gpr_count++;
2225dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.AdjustCFAOffset(kFramePointerSize);
2226dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.RelOffset(DWARFReg(spill.AsCpuRegister().AsRegister()), 0);
2227c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2228fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
22298c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky  // return address then method on stack.
2230c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t rest_of_frame = static_cast<int64_t>(frame_size)
2231c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov                          - (gpr_count * kFramePointerSize)
2232c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov                          - kFramePointerSize /*return address*/;
2233c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  subq(CpuRegister(RSP), Immediate(rest_of_frame));
2234dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(rest_of_frame);
2235547cdfd21ee21e4ab9ca8692d6ef47c62ee7ea52Tong Shen
2236c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  // spill xmms
2237c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t offset = rest_of_frame;
2238c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  for (int i = spill_regs.size() - 1; i >= 0; --i) {
2239c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2240c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsXmmRegister()) {
2241c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      offset -= sizeof(double);
2242c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      movsd(Address(CpuRegister(RSP), offset), spill.AsXmmRegister());
2243dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.RelOffset(DWARFReg(spill.AsXmmRegister().AsFloatRegister()), offset);
2244c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2245c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  }
2246cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe
2247cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  DCHECK_EQ(4U, sizeof(StackReference<mirror::ArtMethod>));
2248c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov
2249cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  movl(Address(CpuRegister(RSP), 0), method_reg.AsX86_64().AsCpuRegister());
2250fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2251fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (size_t i = 0; i < entry_spills.size(); ++i) {
2252fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    ManagedRegisterSpill spill = entry_spills.at(i);
2253fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (spill.AsX86_64().IsCpuRegister()) {
2254fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (spill.getSize() == 8) {
2255dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movq(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()),
2256dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers             spill.AsX86_64().AsCpuRegister());
2257fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2258fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(spill.getSize(), 4);
2259dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movl(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsCpuRegister());
2260fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2261fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2262fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (spill.getSize() == 8) {
2263dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movsd(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister());
2264fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2265fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(spill.getSize(), 4);
2266dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movss(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister());
2267fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2268fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2269fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2270fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2271fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2272fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::RemoveFrame(size_t frame_size,
2273fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                            const std::vector<ManagedRegister>& spill_regs) {
2274fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(frame_size, kStackAlignment);
2275dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.RememberState();
2276c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int gpr_count = 0;
2277c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  // unspill xmms
2278c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  int64_t offset = static_cast<int64_t>(frame_size) - (spill_regs.size() * kFramePointerSize) - 2 * kFramePointerSize;
2279fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  for (size_t i = 0; i < spill_regs.size(); ++i) {
2280c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2281c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsXmmRegister()) {
2282c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      offset += sizeof(double);
2283c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      movsd(spill.AsXmmRegister(), Address(CpuRegister(RSP), offset));
2284dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.Restore(DWARFReg(spill.AsXmmRegister().AsFloatRegister()));
2285c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    } else {
2286c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      gpr_count++;
2287c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2288c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  }
2289dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  int adjust = static_cast<int>(frame_size) - (gpr_count * kFramePointerSize) - kFramePointerSize;
2290dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  addq(CpuRegister(RSP), Immediate(adjust));
2291dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(-adjust);
2292c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov  for (size_t i = 0; i < spill_regs.size(); ++i) {
2293c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64();
2294c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (spill.IsCpuRegister()) {
2295c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      popq(spill.AsCpuRegister());
2296dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.AdjustCFAOffset(-static_cast<int>(kFramePointerSize));
2297dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      cfi_.Restore(DWARFReg(spill.AsCpuRegister().AsRegister()));
2298c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    }
2299fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2300fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  ret();
2301dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  // The CFI should be restored for any code that follows the exit block.
2302dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.RestoreState();
2303dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.DefCFAOffset(frame_size);
2304fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2305fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2306fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::IncreaseFrameSize(size_t adjust) {
2307fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(adjust, kStackAlignment);
23085408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate  addq(CpuRegister(RSP), Immediate(-static_cast<int64_t>(adjust)));
2309dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(adjust);
2310fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2311fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2312fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::DecreaseFrameSize(size_t adjust) {
2313fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_ALIGNED(adjust, kStackAlignment);
2314dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  addq(CpuRegister(RSP), Immediate(adjust));
2315dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  cfi_.AdjustCFAOffset(-adjust);
2316fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2317fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2318fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) {
2319fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2320fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (src.IsNoRegister()) {
2321fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2322fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsCpuRegister()) {
2323fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2324fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(4u, size);
2325dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movl(Address(CpuRegister(RSP), offs), src.AsCpuRegister());
2326fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2327fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(8u, size);
2328dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movq(Address(CpuRegister(RSP), offs), src.AsCpuRegister());
2329fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2330fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsRegisterPair()) {
2331fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2332dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(Address(CpuRegister(RSP), offs), src.AsRegisterPairLow());
2333dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(Address(CpuRegister(RSP), FrameOffset(offs.Int32Value()+4)),
2334fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko         src.AsRegisterPairHigh());
2335fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (src.IsX87Register()) {
2336fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2337dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fstps(Address(CpuRegister(RSP), offs));
2338fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2339dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fstpl(Address(CpuRegister(RSP), offs));
2340fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2341fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2342fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(src.IsXmmRegister());
2343fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2344dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movss(Address(CpuRegister(RSP), offs), src.AsXmmRegister());
2345fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2346dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movsd(Address(CpuRegister(RSP), offs), src.AsXmmRegister());
2347fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2348fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2349fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2350fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2351fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
2352fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2353fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(src.IsCpuRegister());
2354cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  movl(Address(CpuRegister(RSP), dest), src.AsCpuRegister());
2355fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2356fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2357fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
2358fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2359fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(src.IsCpuRegister());
2360dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), dest), src.AsCpuRegister());
2361fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2362fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2363fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
2364dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                            ManagedRegister) {
2365dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(Address(CpuRegister(RSP), dest), Immediate(imm));  // TODO(64) movq?
2366fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2367fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2368dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
2369dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                               ManagedRegister) {
2370fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movl(Address::Absolute(dest, true), Immediate(imm));  // TODO(64) movq?
2371fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2372fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2373dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreStackOffsetToThread64(ThreadOffset<8> thr_offs,
2374dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                 FrameOffset fr_offs,
2375dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                 ManagedRegister mscratch) {
2376fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2377fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2378dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), fr_offs));
2379fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister());
2380fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2381fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2382dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::StoreStackPointerToThread64(ThreadOffset<8> thr_offs) {
2383dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(Address::Absolute(thr_offs, true), CpuRegister(RSP));
2384fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2385fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2386fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::StoreSpanning(FrameOffset /*dst*/, ManagedRegister /*src*/,
2387fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                 FrameOffset /*in_off*/, ManagedRegister /*scratch*/) {
2388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  UNIMPLEMENTED(FATAL);  // this case only currently exists for ARM
2389fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2390fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2391fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) {
2392fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2393fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (dest.IsNoRegister()) {
2394fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2395fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsCpuRegister()) {
2396fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2397fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(4u, size);
2398dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movl(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2399fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2400fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      CHECK_EQ(8u, size);
2401dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2402fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2403fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsRegisterPair()) {
2404fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2405dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(dest.AsRegisterPairLow(), Address(CpuRegister(RSP), src));
2406dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movq(dest.AsRegisterPairHigh(), Address(CpuRegister(RSP), FrameOffset(src.Int32Value()+4)));
2407fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsX87Register()) {
2408fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2409dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      flds(Address(CpuRegister(RSP), src));
2410fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2411dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      fldl(Address(CpuRegister(RSP), src));
2412fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2413fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2414fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(dest.IsXmmRegister());
2415fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2416dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), src));
2417fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2418dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), src));
2419fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2420fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2421fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2422fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2423dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) {
2424fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2425fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (dest.IsNoRegister()) {
2426fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(0u, size);
2427fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsCpuRegister()) {
2428fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(4u, size);
2429dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    gs()->movl(dest.AsCpuRegister(), Address::Absolute(src, true));
2430fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsRegisterPair()) {
2431fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK_EQ(8u, size);
2432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    gs()->movq(dest.AsRegisterPairLow(), Address::Absolute(src, true));
2433fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else if (dest.IsX87Register()) {
2434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->flds(Address::Absolute(src, true));
2436fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2437fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->fldl(Address::Absolute(src, true));
2438fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2439fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2440fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    CHECK(dest.IsXmmRegister());
2441fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (size == 4) {
2442fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->movss(dest.AsXmmRegister(), Address::Absolute(src, true));
2443fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2444fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      gs()->movsd(dest.AsXmmRegister(), Address::Absolute(src, true));
2445fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2446fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2447fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2448fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2449fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadRef(ManagedRegister mdest, FrameOffset  src) {
2450fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2451fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister());
2452dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src));
2453fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2455fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base,
2456fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                           MemberOffset offs) {
2457fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2458fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
2459f889267adadd62c92d1d3726764598946a961c10Hiroshi Yamauchi  movl(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
2460b88f0b16dbaff09a140d2a62b66eca2736ff514bHiroshi Yamauchi  if (kPoisonHeapReferences) {
2461b88f0b16dbaff09a140d2a62b66eca2736ff514bHiroshi Yamauchi    negl(dest.AsCpuRegister());
2462b88f0b16dbaff09a140d2a62b66eca2736ff514bHiroshi Yamauchi  }
2463fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2464fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2465fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
2466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                              Offset offs) {
2467fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2468fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
2469fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
2470fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2471fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2472dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) {
2473fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(dest.IsCpuRegister());
2475fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(dest.AsCpuRegister(), Address::Absolute(offs, true));
2476fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2477fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2478fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::SignExtend(ManagedRegister mreg, size_t size) {
2479fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister reg = mreg.AsX86_64();
2480fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(size == 1 || size == 2) << size;
2481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(reg.IsCpuRegister()) << reg;
2482fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (size == 1) {
2483dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movsxb(reg.AsCpuRegister(), reg.AsCpuRegister());
2484fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2485fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    movsxw(reg.AsCpuRegister(), reg.AsCpuRegister());
2486fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2487fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2488fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2489fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ZeroExtend(ManagedRegister mreg, size_t size) {
2490fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister reg = mreg.AsX86_64();
2491fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(size == 1 || size == 2) << size;
2492fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(reg.IsCpuRegister()) << reg;
2493fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (size == 1) {
2494dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    movzxb(reg.AsCpuRegister(), reg.AsCpuRegister());
2495fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2496fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    movzxw(reg.AsCpuRegister(), reg.AsCpuRegister());
2497fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2498fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2499fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2500fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
2501fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister dest = mdest.AsX86_64();
2502fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister src = msrc.AsX86_64();
2503fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (!dest.Equals(src)) {
2504fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (dest.IsCpuRegister() && src.IsCpuRegister()) {
2505fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      movq(dest.AsCpuRegister(), src.AsCpuRegister());
2506fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else if (src.IsX87Register() && dest.IsXmmRegister()) {
2507fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      // Pass via stack and pop X87 register
2508dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      subl(CpuRegister(RSP), Immediate(16));
2509fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      if (size == 4) {
2510fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(src.AsX87Register(), ST0);
2511dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        fstps(Address(CpuRegister(RSP), 0));
2512dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0));
2513fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      } else {
2514fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko        CHECK_EQ(src.AsX87Register(), ST0);
2515dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        fstpl(Address(CpuRegister(RSP), 0));
2516dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0));
2517fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      }
2518dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      addq(CpuRegister(RSP), Immediate(16));
2519fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    } else {
2520fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      // TODO: x87, SSE
2521fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      UNIMPLEMENTED(FATAL) << ": Move " << dest << ", " << src;
2522fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2523fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2524fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2525fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2526fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::CopyRef(FrameOffset dest, FrameOffset src,
2527fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                           ManagedRegister mscratch) {
2528fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2529fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2530dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), src));
2531dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movl(Address(CpuRegister(RSP), dest), scratch.AsCpuRegister());
2532fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2533fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2534dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CopyRawPtrFromThread64(FrameOffset fr_offs,
2535dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                             ThreadOffset<8> thr_offs,
2536dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                             ManagedRegister mscratch) {
2537fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2538fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2539fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(scratch.AsCpuRegister(), Address::Absolute(thr_offs, true));
2540fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Store(fr_offs, scratch, 8);
2541fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2542fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2543dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CopyRawPtrToThread64(ThreadOffset<8> thr_offs,
2544dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                           FrameOffset fr_offs,
2545dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                           ManagedRegister mscratch) {
2546fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2547fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2548fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Load(scratch, fr_offs, 8);
2549fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister());
2550fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2551fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2552fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, FrameOffset src,
2553fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch,
2554fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        size_t size) {
2555fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2556fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (scratch.IsCpuRegister() && size == 8) {
2557fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, src, 4);
2558fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(dest, scratch, 4);
2559fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, FrameOffset(src.Int32Value() + 4), 4);
2560fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(FrameOffset(dest.Int32Value() + 4), scratch, 4);
2561fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2562fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Load(scratch, src, size);
2563fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Store(dest, scratch, size);
2564fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2565fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2566fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2567fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset /*dst*/, ManagedRegister /*src_base*/, Offset /*src_offset*/,
2568fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister /*scratch*/, size_t /*size*/) {
2569fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  UNIMPLEMENTED(FATAL);
2570fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2571fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2572fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
2573fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister scratch, size_t size) {
2574fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsNoRegister());
2575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2576dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  pushq(Address(CpuRegister(RSP), src));
2577fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(dest_base.AsX86_64().AsCpuRegister(), dest_offset));
2578fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2579fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2580fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
2581fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch, size_t size) {
2582dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2583fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2584dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(scratch, Address(CpuRegister(RSP), src_base));
2585fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(scratch, Address(scratch, src_offset));
2586dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), dest), scratch);
2587fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2588fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2589fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(ManagedRegister dest, Offset dest_offset,
2590fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister src, Offset src_offset,
2591fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister scratch, size_t size) {
2592fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2593fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsNoRegister());
2594fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Address(src.AsX86_64().AsCpuRegister(), src_offset));
2595fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(dest.AsX86_64().AsCpuRegister(), dest_offset));
2596fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2597fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2598fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
2599fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                        ManagedRegister mscratch, size_t size) {
2600dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2601fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(size, 4u);
2602fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK_EQ(dest.Int32Value(), src.Int32Value());
2603dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(scratch, Address(CpuRegister(RSP), src));
2604fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  pushq(Address(scratch, src_offset));
2605fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  popq(Address(scratch, dest_offset));
2606fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2607fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2608fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::MemoryBarrier(ManagedRegister) {
2609fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  mfence();
2610fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2611fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2612eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::CreateHandleScopeEntry(ManagedRegister mout_reg,
2613eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                   FrameOffset handle_scope_offset,
2614fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   ManagedRegister min_reg, bool null_allowed) {
2615fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister out_reg = mout_reg.AsX86_64();
2616fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister in_reg = min_reg.AsX86_64();
2617fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (in_reg.IsNoRegister()) {  // TODO(64): && null_allowed
2618fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // Use out_reg as indicator of NULL
2619fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    in_reg = out_reg;
2620fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    // TODO: movzwl
2621eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    movl(in_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2622fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2623fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(in_reg.IsCpuRegister());
2624fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(out_reg.IsCpuRegister());
2625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  VerifyObject(in_reg, null_allowed);
2626fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (null_allowed) {
2627fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Label null_arg;
2628fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    if (!out_reg.Equals(in_reg)) {
2629fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
2630fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    }
2631fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
2632fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    j(kZero, &null_arg);
2633eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2634fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Bind(&null_arg);
2635fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2636eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2637fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2638fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2639fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2640eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::CreateHandleScopeEntry(FrameOffset out_off,
2641eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                   FrameOffset handle_scope_offset,
2642fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   ManagedRegister mscratch,
2643fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                   bool null_allowed) {
2644fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2645fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(scratch.IsCpuRegister());
2646fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (null_allowed) {
2647fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Label null_arg;
2648eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2649fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    testl(scratch.AsCpuRegister(), scratch.AsCpuRegister());
2650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    j(kZero, &null_arg);
2651eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    Bind(&null_arg);
2653fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  } else {
2654eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset));
2655fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2656fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Store(out_off, scratch, 8);
2657fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2658fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2659eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Given a handle scope entry, load the associated reference.
2660eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiervoid X86_64Assembler::LoadReferenceFromHandleScope(ManagedRegister mout_reg,
2661fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko                                         ManagedRegister min_reg) {
2662fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister out_reg = mout_reg.AsX86_64();
2663fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister in_reg = min_reg.AsX86_64();
2664fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(out_reg.IsCpuRegister());
2665fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(in_reg.IsCpuRegister());
2666fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Label null_arg;
2667fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (!out_reg.Equals(in_reg)) {
2668fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
2669fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2670fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
2671fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  j(kZero, &null_arg);
2672fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  movq(out_reg.AsCpuRegister(), Address(in_reg.AsCpuRegister(), 0));
2673fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  Bind(&null_arg);
2674fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2675fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2676fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
2677fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: not validating references
2678fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2679fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2680fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
2681fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: not validating references
2682fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2683fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2684fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Call(ManagedRegister mbase, Offset offset, ManagedRegister) {
2685fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister base = mbase.AsX86_64();
2686fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  CHECK(base.IsCpuRegister());
2687fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  call(Address(base.AsCpuRegister(), offset.Int32Value()));
2688fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // TODO: place reference map on call
2689fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2690fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2691fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) {
2692dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister();
2693cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  movl(scratch, Address(CpuRegister(RSP), base));
2694fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  call(Address(scratch, offset));
2695fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2696fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2697dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::CallFromThread64(ThreadOffset<8> offset, ManagedRegister /*mscratch*/) {
2698fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  gs()->call(Address::Absolute(offset, true));
2699fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2700fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2701fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::GetCurrentThread(ManagedRegister tr) {
2702dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(tr.AsX86_64().AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true));
2703fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2704fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2705dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64Assembler::GetCurrentThread(FrameOffset offset, ManagedRegister mscratch) {
2706fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64ManagedRegister scratch = mscratch.AsX86_64();
2707dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->movq(scratch.AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true));
2708dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  movq(Address(CpuRegister(RSP), offset), scratch.AsCpuRegister());
2709fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2710fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2711dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Slowpath entered when Thread::Current()->_exception is non-null
2712dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass X86_64ExceptionSlowPath FINAL : public SlowPath {
2713dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers public:
2714dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  explicit X86_64ExceptionSlowPath(size_t stack_adjust) : stack_adjust_(stack_adjust) {}
2715dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  virtual void Emit(Assembler *sp_asm) OVERRIDE;
2716dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers private:
2717dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  const size_t stack_adjust_;
2718dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers};
2719dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2720fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64Assembler::ExceptionPoll(ManagedRegister /*scratch*/, size_t stack_adjust) {
2721dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  X86_64ExceptionSlowPath* slow = new X86_64ExceptionSlowPath(stack_adjust);
2722fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  buffer_.EnqueueSlowPath(slow);
2723dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  gs()->cmpl(Address::Absolute(Thread::ExceptionOffset<8>(), true), Immediate(0));
2724fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  j(kNotEqual, slow->Entry());
2725fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2726fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2727dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid X86_64ExceptionSlowPath::Emit(Assembler *sasm) {
2728fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  X86_64Assembler* sp_asm = down_cast<X86_64Assembler*>(sasm);
2729fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#define __ sp_asm->
2730fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  __ Bind(&entry_);
2731fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // Note: the return value is dead
2732fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  if (stack_adjust_ != 0) {  // Fix up the frame.
2733fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    __ DecreaseFrameSize(stack_adjust_);
2734fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
2735dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Pass exception as argument in RDI
2736dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  __ gs()->movq(CpuRegister(RDI), Address::Absolute(Thread::ExceptionOffset<8>(), true));
2737dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(8, pDeliverException), true));
2738fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // this call should never return
2739fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  __ int3();
2740fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#undef __
2741fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
2742fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
2743f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellvoid X86_64Assembler::AddConstantArea() {
2744f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  const std::vector<int32_t>& area = constant_area_.GetBuffer();
274539dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell  for (size_t i = 0, e = area.size(); i < e; i++) {
2746f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2747f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    EmitInt32(area[i]);
2748f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2749f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2750f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2751f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddInt32(int32_t v) {
275239dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell  for (size_t i = 0, e = buffer_.size(); i < e; i++) {
2753f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    if (v == buffer_[i]) {
2754f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell      return i * elem_size_;
2755f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    }
2756f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2757f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2758f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Didn't match anything.
2759f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int result = buffer_.size() * elem_size_;
2760f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v);
2761f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return result;
2762f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2763f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2764f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddInt64(int64_t v) {
2765f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int32_t v_low = v;
2766f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int32_t v_high = v >> 32;
2767f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  if (buffer_.size() > 1) {
2768f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    // Ensure we don't pass the end of the buffer.
276939dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell    for (size_t i = 0, e = buffer_.size() - 1; i < e; i++) {
277039dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell      if (v_low == buffer_[i] && v_high == buffer_[i + 1]) {
2771f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell        return i * elem_size_;
2772f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell      }
2773f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell    }
2774f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  }
2775f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2776f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Didn't match anything.
2777f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  int result = buffer_.size() * elem_size_;
2778f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v_low);
2779f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  buffer_.push_back(v_high);
2780f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return result;
2781f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2782f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2783f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddDouble(double v) {
2784f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Treat the value as a 64-bit integer value.
2785f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return AddInt64(bit_cast<int64_t, double>(v));
2786f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2787f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2788f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellint ConstantArea::AddFloat(float v) {
2789f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  // Treat the value as a 32-bit integer value.
2790f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell  return AddInt32(bit_cast<int32_t, float>(v));
2791f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}
2792f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell
2793fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}  // namespace x86_64
2794fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}  // namespace art
2795