Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // NOLINT 5 #include "vm/globals.h" // NOLINT
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/heap.h" 10 #include "vm/heap.h"
11 #include "vm/instructions.h" 11 #include "vm/instructions.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/memory_region.h" 13 #include "vm/memory_region.h"
14 #include "vm/runtime_entry.h" 14 #include "vm/runtime_entry.h"
15 #include "vm/stack_frame.h" 15 #include "vm/stack_frame.h"
16 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
17 17
18 namespace dart { 18 namespace dart {
19 19
20 DECLARE_FLAG(bool, check_code_pointer); 20 DECLARE_FLAG(bool, check_code_pointer);
21 DECLARE_FLAG(bool, inline_alloc); 21 DECLARE_FLAG(bool, inline_alloc);
22 22
23
24 Assembler::Assembler(bool use_far_branches) 23 Assembler::Assembler(bool use_far_branches)
25 : buffer_(), 24 : buffer_(),
26 prologue_offset_(-1), 25 prologue_offset_(-1),
27 has_single_entry_point_(true), 26 has_single_entry_point_(true),
28 comments_(), 27 comments_(),
29 constant_pool_allowed_(false) { 28 constant_pool_allowed_(false) {
30 // Far branching mode is only needed and implemented for ARM. 29 // Far branching mode is only needed and implemented for ARM.
31 ASSERT(!use_far_branches); 30 ASSERT(!use_far_branches);
32 } 31 }
33 32
34
35 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { 33 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
36 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); 34 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length);
37 } 35 }
38 36
39
40 void Assembler::call(Register reg) { 37 void Assembler::call(Register reg) {
41 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 38 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
42 Operand operand(reg); 39 Operand operand(reg);
43 EmitOperandREX(2, operand, REX_NONE); 40 EmitOperandREX(2, operand, REX_NONE);
44 EmitUint8(0xFF); 41 EmitUint8(0xFF);
45 EmitOperand(2, operand); 42 EmitOperand(2, operand);
46 } 43 }
47 44
48
49 void Assembler::call(const Address& address) { 45 void Assembler::call(const Address& address) {
50 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 46 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
51 EmitOperandREX(2, address, REX_NONE); 47 EmitOperandREX(2, address, REX_NONE);
52 EmitUint8(0xFF); 48 EmitUint8(0xFF);
53 EmitOperand(2, address); 49 EmitOperand(2, address);
54 } 50 }
55 51
56
57 void Assembler::call(Label* label) { 52 void Assembler::call(Label* label) {
58 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 53 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
59 static const int kSize = 5; 54 static const int kSize = 5;
60 EmitUint8(0xE8); 55 EmitUint8(0xE8);
61 EmitLabel(label, kSize); 56 EmitLabel(label, kSize);
62 } 57 }
63 58
64
65 void Assembler::LoadNativeEntry(Register dst, 59 void Assembler::LoadNativeEntry(Register dst,
66 const ExternalLabel* label, 60 const ExternalLabel* label,
67 Patchability patchable) { 61 Patchability patchable) {
68 const int32_t offset = ObjectPool::element_offset( 62 const int32_t offset = ObjectPool::element_offset(
69 object_pool_wrapper_.FindNativeEntry(label, patchable)); 63 object_pool_wrapper_.FindNativeEntry(label, patchable));
70 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag); 64 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
71 } 65 }
72 66
73
74 void Assembler::call(const ExternalLabel* label) { 67 void Assembler::call(const ExternalLabel* label) {
75 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. 68 { // Encode movq(TMP, Immediate(label->address())), but always as imm64.
76 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 69 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
77 EmitRegisterREX(TMP, REX_W); 70 EmitRegisterREX(TMP, REX_W);
78 EmitUint8(0xB8 | (TMP & 7)); 71 EmitUint8(0xB8 | (TMP & 7));
79 EmitInt64(label->address()); 72 EmitInt64(label->address());
80 } 73 }
81 call(TMP); 74 call(TMP);
82 } 75 }
83 76
84
85 void Assembler::CallPatchable(const StubEntry& stub_entry) { 77 void Assembler::CallPatchable(const StubEntry& stub_entry) {
86 ASSERT(constant_pool_allowed()); 78 ASSERT(constant_pool_allowed());
87 const Code& target = Code::ZoneHandle(stub_entry.code()); 79 const Code& target = Code::ZoneHandle(stub_entry.code());
88 intptr_t call_start = buffer_.GetPosition(); 80 intptr_t call_start = buffer_.GetPosition();
89 const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable); 81 const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable);
90 const int32_t offset = ObjectPool::element_offset(idx); 82 const int32_t offset = ObjectPool::element_offset(idx);
91 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); 83 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
92 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); 84 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
93 call(TMP); 85 call(TMP);
94 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); 86 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize);
95 } 87 }
96 88
97
98 void Assembler::CallWithEquivalence(const StubEntry& stub_entry, 89 void Assembler::CallWithEquivalence(const StubEntry& stub_entry,
99 const Object& equivalence) { 90 const Object& equivalence) {
100 ASSERT(constant_pool_allowed()); 91 ASSERT(constant_pool_allowed());
101 const Code& target = Code::ZoneHandle(stub_entry.code()); 92 const Code& target = Code::ZoneHandle(stub_entry.code());
102 const intptr_t idx = object_pool_wrapper_.FindObject(target, equivalence); 93 const intptr_t idx = object_pool_wrapper_.FindObject(target, equivalence);
103 const int32_t offset = ObjectPool::element_offset(idx); 94 const int32_t offset = ObjectPool::element_offset(idx);
104 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); 95 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
105 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); 96 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
106 call(TMP); 97 call(TMP);
107 } 98 }
108 99
109
110 void Assembler::Call(const StubEntry& stub_entry) { 100 void Assembler::Call(const StubEntry& stub_entry) {
111 ASSERT(constant_pool_allowed()); 101 ASSERT(constant_pool_allowed());
112 const Code& target = Code::ZoneHandle(stub_entry.code()); 102 const Code& target = Code::ZoneHandle(stub_entry.code());
113 const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable); 103 const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable);
114 const int32_t offset = ObjectPool::element_offset(idx); 104 const int32_t offset = ObjectPool::element_offset(idx);
115 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); 105 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
116 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); 106 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
117 call(TMP); 107 call(TMP);
118 } 108 }
119 109
120
121 void Assembler::CallToRuntime() { 110 void Assembler::CallToRuntime() {
122 movq(TMP, Address(THR, Thread::call_to_runtime_entry_point_offset())); 111 movq(TMP, Address(THR, Thread::call_to_runtime_entry_point_offset()));
123 movq(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset())); 112 movq(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
124 call(TMP); 113 call(TMP);
125 } 114 }
126 115
127
128 void Assembler::pushq(Register reg) { 116 void Assembler::pushq(Register reg) {
129 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 117 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
130 EmitRegisterREX(reg, REX_NONE); 118 EmitRegisterREX(reg, REX_NONE);
131 EmitUint8(0x50 | (reg & 7)); 119 EmitUint8(0x50 | (reg & 7));
132 } 120 }
133 121
134
135 void Assembler::pushq(const Address& address) { 122 void Assembler::pushq(const Address& address) {
136 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 123 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
137 EmitOperandREX(6, address, REX_NONE); 124 EmitOperandREX(6, address, REX_NONE);
138 EmitUint8(0xFF); 125 EmitUint8(0xFF);
139 EmitOperand(6, address); 126 EmitOperand(6, address);
140 } 127 }
141 128
142
143 void Assembler::pushq(const Immediate& imm) { 129 void Assembler::pushq(const Immediate& imm) {
144 if (imm.is_int8()) { 130 if (imm.is_int8()) {
145 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 131 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
146 EmitUint8(0x6A); 132 EmitUint8(0x6A);
147 EmitUint8(imm.value() & 0xFF); 133 EmitUint8(imm.value() & 0xFF);
148 } else if (imm.is_int32()) { 134 } else if (imm.is_int32()) {
149 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 135 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
150 EmitUint8(0x68); 136 EmitUint8(0x68);
151 EmitImmediate(imm); 137 EmitImmediate(imm);
152 } else { 138 } else {
153 movq(TMP, imm); 139 movq(TMP, imm);
154 pushq(TMP); 140 pushq(TMP);
155 } 141 }
156 } 142 }
157 143
158
159 void Assembler::PushImmediate(const Immediate& imm) { 144 void Assembler::PushImmediate(const Immediate& imm) {
160 if (imm.is_int32()) { 145 if (imm.is_int32()) {
161 pushq(imm); 146 pushq(imm);
162 } else { 147 } else {
163 LoadImmediate(TMP, imm); 148 LoadImmediate(TMP, imm);
164 pushq(TMP); 149 pushq(TMP);
165 } 150 }
166 } 151 }
167 152
168
169 void Assembler::popq(Register reg) { 153 void Assembler::popq(Register reg) {
170 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 154 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
171 EmitRegisterREX(reg, REX_NONE); 155 EmitRegisterREX(reg, REX_NONE);
172 EmitUint8(0x58 | (reg & 7)); 156 EmitUint8(0x58 | (reg & 7));
173 } 157 }
174 158
175
176 void Assembler::popq(const Address& address) { 159 void Assembler::popq(const Address& address) {
177 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 160 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
178 EmitOperandREX(0, address, REX_NONE); 161 EmitOperandREX(0, address, REX_NONE);
179 EmitUint8(0x8F); 162 EmitUint8(0x8F);
180 EmitOperand(0, address); 163 EmitOperand(0, address);
181 } 164 }
182 165
183
184 void Assembler::setcc(Condition condition, ByteRegister dst) { 166 void Assembler::setcc(Condition condition, ByteRegister dst) {
185 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 167 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
186 EmitUint8(0x0F); 168 EmitUint8(0x0F);
187 EmitUint8(0x90 + condition); 169 EmitUint8(0x90 + condition);
188 EmitUint8(0xC0 + dst); 170 EmitUint8(0xC0 + dst);
189 } 171 }
190 172
191
192 void Assembler::movl(Register dst, Register src) { 173 void Assembler::movl(Register dst, Register src) {
193 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 174 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
194 Operand operand(src); 175 Operand operand(src);
195 EmitOperandREX(dst, operand, REX_NONE); 176 EmitOperandREX(dst, operand, REX_NONE);
196 EmitUint8(0x8B); 177 EmitUint8(0x8B);
197 EmitOperand(dst & 7, operand); 178 EmitOperand(dst & 7, operand);
198 } 179 }
199 180
200
201 void Assembler::movl(Register dst, const Immediate& imm) { 181 void Assembler::movl(Register dst, const Immediate& imm) {
202 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 182 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
203 Operand operand(dst); 183 Operand operand(dst);
204 EmitOperandREX(0, operand, REX_NONE); 184 EmitOperandREX(0, operand, REX_NONE);
205 EmitUint8(0xC7); 185 EmitUint8(0xC7);
206 EmitOperand(0, operand); 186 EmitOperand(0, operand);
207 ASSERT(imm.is_int32()); 187 ASSERT(imm.is_int32());
208 EmitImmediate(imm); 188 EmitImmediate(imm);
209 } 189 }
210 190
211
212 void Assembler::movl(Register dst, const Address& src) { 191 void Assembler::movl(Register dst, const Address& src) {
213 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 192 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
214 EmitOperandREX(dst, src, REX_NONE); 193 EmitOperandREX(dst, src, REX_NONE);
215 EmitUint8(0x8B); 194 EmitUint8(0x8B);
216 EmitOperand(dst & 7, src); 195 EmitOperand(dst & 7, src);
217 } 196 }
218 197
219
220 void Assembler::movl(const Address& dst, Register src) { 198 void Assembler::movl(const Address& dst, Register src) {
221 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 199 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
222 EmitOperandREX(src, dst, REX_NONE); 200 EmitOperandREX(src, dst, REX_NONE);
223 EmitUint8(0x89); 201 EmitUint8(0x89);
224 EmitOperand(src & 7, dst); 202 EmitOperand(src & 7, dst);
225 } 203 }
226 204
227
228 void Assembler::movl(const Address& dst, const Immediate& imm) { 205 void Assembler::movl(const Address& dst, const Immediate& imm) {
229 movl(TMP, imm); 206 movl(TMP, imm);
230 movl(dst, TMP); 207 movl(dst, TMP);
231 } 208 }
232 209
233
234 void Assembler::movzxb(Register dst, Register src) { 210 void Assembler::movzxb(Register dst, Register src) {
235 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 211 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
236 Operand operand(src); 212 Operand operand(src);
237 EmitOperandREX(dst, operand, REX_W); 213 EmitOperandREX(dst, operand, REX_W);
238 EmitUint8(0x0F); 214 EmitUint8(0x0F);
239 EmitUint8(0xB6); 215 EmitUint8(0xB6);
240 EmitOperand(dst & 7, operand); 216 EmitOperand(dst & 7, operand);
241 } 217 }
242 218
243
244 void Assembler::movzxb(Register dst, const Address& src) { 219 void Assembler::movzxb(Register dst, const Address& src) {
245 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 220 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
246 EmitOperandREX(dst, src, REX_W); 221 EmitOperandREX(dst, src, REX_W);
247 EmitUint8(0x0F); 222 EmitUint8(0x0F);
248 EmitUint8(0xB6); 223 EmitUint8(0xB6);
249 EmitOperand(dst & 7, src); 224 EmitOperand(dst & 7, src);
250 } 225 }
251 226
252
253 void Assembler::movsxb(Register dst, Register src) { 227 void Assembler::movsxb(Register dst, Register src) {
254 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 228 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
255 Operand operand(src); 229 Operand operand(src);
256 EmitOperandREX(dst, operand, REX_W); 230 EmitOperandREX(dst, operand, REX_W);
257 EmitUint8(0x0F); 231 EmitUint8(0x0F);
258 EmitUint8(0xBE); 232 EmitUint8(0xBE);
259 EmitOperand(dst & 7, operand); 233 EmitOperand(dst & 7, operand);
260 } 234 }
261 235
262
263 void Assembler::movsxb(Register dst, const Address& src) { 236 void Assembler::movsxb(Register dst, const Address& src) {
264 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 237 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
265 EmitOperandREX(dst, src, REX_W); 238 EmitOperandREX(dst, src, REX_W);
266 EmitUint8(0x0F); 239 EmitUint8(0x0F);
267 EmitUint8(0xBE); 240 EmitUint8(0xBE);
268 EmitOperand(dst & 7, src); 241 EmitOperand(dst & 7, src);
269 } 242 }
270 243
271
272 void Assembler::movb(Register dst, const Address& src) { 244 void Assembler::movb(Register dst, const Address& src) {
273 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 245 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
274 EmitOperandREX(dst, src, REX_NONE); 246 EmitOperandREX(dst, src, REX_NONE);
275 EmitUint8(0x8A); 247 EmitUint8(0x8A);
276 EmitOperand(dst & 7, src); 248 EmitOperand(dst & 7, src);
277 } 249 }
278 250
279
280 void Assembler::movb(const Address& dst, const Immediate& imm) { 251 void Assembler::movb(const Address& dst, const Immediate& imm) {
281 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 252 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
282 EmitOperandREX(0, dst, REX_NONE); 253 EmitOperandREX(0, dst, REX_NONE);
283 EmitUint8(0xC6); 254 EmitUint8(0xC6);
284 EmitOperand(0, dst); 255 EmitOperand(0, dst);
285 ASSERT(imm.is_int8()); 256 ASSERT(imm.is_int8());
286 EmitUint8(imm.value() & 0xFF); 257 EmitUint8(imm.value() & 0xFF);
287 } 258 }
288 259
289
290 void Assembler::movb(const Address& dst, Register src) { 260 void Assembler::movb(const Address& dst, Register src) {
291 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 261 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
292 EmitOperandREX(src, dst, REX_NONE); 262 EmitOperandREX(src, dst, REX_NONE);
293 EmitUint8(0x88); 263 EmitUint8(0x88);
294 EmitOperand(src & 7, dst); 264 EmitOperand(src & 7, dst);
295 } 265 }
296 266
297
298 void Assembler::movzxw(Register dst, Register src) { 267 void Assembler::movzxw(Register dst, Register src) {
299 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 268 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
300 Operand operand(src); 269 Operand operand(src);
301 EmitOperandREX(dst, operand, REX_W); 270 EmitOperandREX(dst, operand, REX_W);
302 EmitUint8(0x0F); 271 EmitUint8(0x0F);
303 EmitUint8(0xB7); 272 EmitUint8(0xB7);
304 EmitOperand(dst & 7, operand); 273 EmitOperand(dst & 7, operand);
305 } 274 }
306 275
307
308 void Assembler::movzxw(Register dst, const Address& src) { 276 void Assembler::movzxw(Register dst, const Address& src) {
309 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 277 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
310 EmitOperandREX(dst, src, REX_W); 278 EmitOperandREX(dst, src, REX_W);
311 EmitUint8(0x0F); 279 EmitUint8(0x0F);
312 EmitUint8(0xB7); 280 EmitUint8(0xB7);
313 EmitOperand(dst & 7, src); 281 EmitOperand(dst & 7, src);
314 } 282 }
315 283
316
317 void Assembler::movsxw(Register dst, Register src) { 284 void Assembler::movsxw(Register dst, Register src) {
318 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 285 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
319 Operand operand(src); 286 Operand operand(src);
320 EmitOperandREX(dst, operand, REX_W); 287 EmitOperandREX(dst, operand, REX_W);
321 EmitUint8(0x0F); 288 EmitUint8(0x0F);
322 EmitUint8(0xBF); 289 EmitUint8(0xBF);
323 EmitOperand(dst & 7, operand); 290 EmitOperand(dst & 7, operand);
324 } 291 }
325 292
326
327 void Assembler::movsxw(Register dst, const Address& src) { 293 void Assembler::movsxw(Register dst, const Address& src) {
328 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 294 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
329 EmitOperandREX(dst, src, REX_W); 295 EmitOperandREX(dst, src, REX_W);
330 EmitUint8(0x0F); 296 EmitUint8(0x0F);
331 EmitUint8(0xBF); 297 EmitUint8(0xBF);
332 EmitOperand(dst & 7, src); 298 EmitOperand(dst & 7, src);
333 } 299 }
334 300
335
336 void Assembler::movw(Register dst, const Address& src) { 301 void Assembler::movw(Register dst, const Address& src) {
337 FATAL("Use movzxw or movsxw instead."); 302 FATAL("Use movzxw or movsxw instead.");
338 } 303 }
339 304
340
341 void Assembler::movw(const Address& dst, Register src) { 305 void Assembler::movw(const Address& dst, Register src) {
342 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 306 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
343 EmitOperandSizeOverride(); 307 EmitOperandSizeOverride();
344 EmitOperandREX(src, dst, REX_NONE); 308 EmitOperandREX(src, dst, REX_NONE);
345 EmitUint8(0x89); 309 EmitUint8(0x89);
346 EmitOperand(src & 7, dst); 310 EmitOperand(src & 7, dst);
347 } 311 }
348 312
349
350 void Assembler::movw(const Address& dst, const Immediate& imm) { 313 void Assembler::movw(const Address& dst, const Immediate& imm) {
351 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 314 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
352 EmitOperandSizeOverride(); 315 EmitOperandSizeOverride();
353 EmitOperandREX(0, dst, REX_NONE); 316 EmitOperandREX(0, dst, REX_NONE);
354 EmitUint8(0xC7); 317 EmitUint8(0xC7);
355 EmitOperand(0, dst); 318 EmitOperand(0, dst);
356 EmitUint8(imm.value() & 0xFF); 319 EmitUint8(imm.value() & 0xFF);
357 EmitUint8((imm.value() >> 8) & 0xFF); 320 EmitUint8((imm.value() >> 8) & 0xFF);
358 } 321 }
359 322
360
361 void Assembler::movq(Register dst, const Immediate& imm) { 323 void Assembler::movq(Register dst, const Immediate& imm) {
362 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 324 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
363 if (imm.is_int32()) { 325 if (imm.is_int32()) {
364 Operand operand(dst); 326 Operand operand(dst);
365 EmitOperandREX(0, operand, REX_W); 327 EmitOperandREX(0, operand, REX_W);
366 EmitUint8(0xC7); 328 EmitUint8(0xC7);
367 EmitOperand(0, operand); 329 EmitOperand(0, operand);
368 } else { 330 } else {
369 EmitRegisterREX(dst, REX_W); 331 EmitRegisterREX(dst, REX_W);
370 EmitUint8(0xB8 | (dst & 7)); 332 EmitUint8(0xB8 | (dst & 7));
371 } 333 }
372 EmitImmediate(imm); 334 EmitImmediate(imm);
373 } 335 }
374 336
375
376 // Use 0x89 encoding (instead of 0x8B encoding), which is expected by gdb64 337 // Use 0x89 encoding (instead of 0x8B encoding), which is expected by gdb64
377 // older than 7.3.1-gg5 when disassembling a function's prologue (movq rbp, rsp) 338 // older than 7.3.1-gg5 when disassembling a function's prologue (movq rbp, rsp)
378 // for proper unwinding of Dart frames (use --generate_gdb_symbols and -O0). 339 // for proper unwinding of Dart frames (use --generate_gdb_symbols and -O0).
379 void Assembler::movq(Register dst, Register src) { 340 void Assembler::movq(Register dst, Register src) {
380 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 341 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
381 Operand operand(dst); 342 Operand operand(dst);
382 EmitOperandREX(src, operand, REX_W); 343 EmitOperandREX(src, operand, REX_W);
383 EmitUint8(0x89); 344 EmitUint8(0x89);
384 EmitOperand(src & 7, operand); 345 EmitOperand(src & 7, operand);
385 } 346 }
386 347
387
388 void Assembler::movq(Register dst, const Address& src) { 348 void Assembler::movq(Register dst, const Address& src) {
389 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 349 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
390 EmitOperandREX(dst, src, REX_W); 350 EmitOperandREX(dst, src, REX_W);
391 EmitUint8(0x8B); 351 EmitUint8(0x8B);
392 EmitOperand(dst & 7, src); 352 EmitOperand(dst & 7, src);
393 } 353 }
394 354
395
396 void Assembler::movq(const Address& dst, Register src) { 355 void Assembler::movq(const Address& dst, Register src) {
397 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 356 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
398 EmitOperandREX(src, dst, REX_W); 357 EmitOperandREX(src, dst, REX_W);
399 EmitUint8(0x89); 358 EmitUint8(0x89);
400 EmitOperand(src & 7, dst); 359 EmitOperand(src & 7, dst);
401 } 360 }
402 361
403
404 void Assembler::movq(const Address& dst, const Immediate& imm) { 362 void Assembler::movq(const Address& dst, const Immediate& imm) {
405 if (imm.is_int32()) { 363 if (imm.is_int32()) {
406 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 364 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
407 Operand operand(dst); 365 Operand operand(dst);
408 EmitOperandREX(0, operand, REX_W); 366 EmitOperandREX(0, operand, REX_W);
409 EmitUint8(0xC7); 367 EmitUint8(0xC7);
410 EmitOperand(0, operand); 368 EmitOperand(0, operand);
411 EmitImmediate(imm); 369 EmitImmediate(imm);
412 } else { 370 } else {
413 movq(TMP, imm); 371 movq(TMP, imm);
414 movq(dst, TMP); 372 movq(dst, TMP);
415 } 373 }
416 } 374 }
417 375
418
419 void Assembler::movsxd(Register dst, Register src) { 376 void Assembler::movsxd(Register dst, Register src) {
420 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 377 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
421 Operand operand(src); 378 Operand operand(src);
422 EmitOperandREX(dst, operand, REX_W); 379 EmitOperandREX(dst, operand, REX_W);
423 EmitUint8(0x63); 380 EmitUint8(0x63);
424 EmitOperand(dst & 7, operand); 381 EmitOperand(dst & 7, operand);
425 } 382 }
426 383
427
428 void Assembler::movsxd(Register dst, const Address& src) { 384 void Assembler::movsxd(Register dst, const Address& src) {
429 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 385 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
430 EmitOperandREX(dst, src, REX_W); 386 EmitOperandREX(dst, src, REX_W);
431 EmitUint8(0x63); 387 EmitUint8(0x63);
432 EmitOperand(dst & 7, src); 388 EmitOperand(dst & 7, src);
433 } 389 }
434 390
435
436 void Assembler::rep_movsb() { 391 void Assembler::rep_movsb() {
437 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 392 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
438 EmitUint8(0xF3); 393 EmitUint8(0xF3);
439 EmitUint8(0xA4); 394 EmitUint8(0xA4);
440 } 395 }
441 396
442
443 void Assembler::leaq(Register dst, const Address& src) { 397 void Assembler::leaq(Register dst, const Address& src) {
444 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 398 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
445 EmitOperandREX(dst, src, REX_W); 399 EmitOperandREX(dst, src, REX_W);
446 EmitUint8(0x8D); 400 EmitUint8(0x8D);
447 EmitOperand(dst & 7, src); 401 EmitOperand(dst & 7, src);
448 } 402 }
449 403
450
451 void Assembler::cmovnoq(Register dst, Register src) { 404 void Assembler::cmovnoq(Register dst, Register src) {
452 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 405 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
453 Operand operand(src); 406 Operand operand(src);
454 EmitOperandREX(dst, operand, REX_W); 407 EmitOperandREX(dst, operand, REX_W);
455 EmitUint8(0x0F); 408 EmitUint8(0x0F);
456 EmitUint8(0x41); 409 EmitUint8(0x41);
457 EmitOperand(dst & 7, operand); 410 EmitOperand(dst & 7, operand);
458 } 411 }
459 412
460
461 void Assembler::cmoveq(Register dst, Register src) { 413 void Assembler::cmoveq(Register dst, Register src) {
462 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 414 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
463 Operand operand(src); 415 Operand operand(src);
464 EmitOperandREX(dst, operand, REX_W); 416 EmitOperandREX(dst, operand, REX_W);
465 EmitUint8(0x0F); 417 EmitUint8(0x0F);
466 EmitUint8(0x44); 418 EmitUint8(0x44);
467 EmitOperand(dst & 7, operand); 419 EmitOperand(dst & 7, operand);
468 } 420 }
469 421
470
471 void Assembler::cmovgeq(Register dst, Register src) { 422 void Assembler::cmovgeq(Register dst, Register src) {
472 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 423 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
473 Operand operand(src); 424 Operand operand(src);
474 EmitOperandREX(dst, operand, REX_W); 425 EmitOperandREX(dst, operand, REX_W);
475 EmitUint8(0x0F); 426 EmitUint8(0x0F);
476 EmitUint8(0x4D); 427 EmitUint8(0x4D);
477 EmitOperand(dst & 7, operand); 428 EmitOperand(dst & 7, operand);
478 } 429 }
479 430
480
481 void Assembler::cmovlessq(Register dst, Register src) { 431 void Assembler::cmovlessq(Register dst, Register src) {
482 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 432 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
483 Operand operand(src); 433 Operand operand(src);
484 EmitOperandREX(dst, operand, REX_W); 434 EmitOperandREX(dst, operand, REX_W);
485 EmitUint8(0x0F); 435 EmitUint8(0x0F);
486 EmitUint8(0x4C); 436 EmitUint8(0x4C);
487 EmitOperand(dst & 7, operand); 437 EmitOperand(dst & 7, operand);
488 } 438 }
489 439
490
491 void Assembler::movss(XmmRegister dst, const Address& src) { 440 void Assembler::movss(XmmRegister dst, const Address& src) {
492 ASSERT(dst <= XMM15); 441 ASSERT(dst <= XMM15);
493 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 442 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
494 EmitUint8(0xF3); 443 EmitUint8(0xF3);
495 EmitREX_RB(dst, src); 444 EmitREX_RB(dst, src);
496 EmitUint8(0x0F); 445 EmitUint8(0x0F);
497 EmitUint8(0x10); 446 EmitUint8(0x10);
498 EmitOperand(dst & 7, src); 447 EmitOperand(dst & 7, src);
499 } 448 }
500 449
501
502 void Assembler::movss(const Address& dst, XmmRegister src) { 450 void Assembler::movss(const Address& dst, XmmRegister src) {
503 ASSERT(src <= XMM15); 451 ASSERT(src <= XMM15);
504 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 452 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
505 EmitUint8(0xF3); 453 EmitUint8(0xF3);
506 EmitREX_RB(src, dst); 454 EmitREX_RB(src, dst);
507 EmitUint8(0x0F); 455 EmitUint8(0x0F);
508 EmitUint8(0x11); 456 EmitUint8(0x11);
509 EmitOperand(src & 7, dst); 457 EmitOperand(src & 7, dst);
510 } 458 }
511 459
512
513 void Assembler::movss(XmmRegister dst, XmmRegister src) { 460 void Assembler::movss(XmmRegister dst, XmmRegister src) {
514 ASSERT(src <= XMM15); 461 ASSERT(src <= XMM15);
515 ASSERT(dst <= XMM15); 462 ASSERT(dst <= XMM15);
516 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 463 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
517 EmitUint8(0xF3); 464 EmitUint8(0xF3);
518 EmitREX_RB(src, dst); 465 EmitREX_RB(src, dst);
519 EmitUint8(0x0F); 466 EmitUint8(0x0F);
520 EmitUint8(0x11); 467 EmitUint8(0x11);
521 EmitXmmRegisterOperand(src & 7, dst); 468 EmitXmmRegisterOperand(src & 7, dst);
522 } 469 }
523 470
524
525 void Assembler::movd(XmmRegister dst, Register src) { 471 void Assembler::movd(XmmRegister dst, Register src) {
526 ASSERT(dst <= XMM15); 472 ASSERT(dst <= XMM15);
527 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 473 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
528 EmitUint8(0x66); 474 EmitUint8(0x66);
529 EmitREX_RB(dst, src); 475 EmitREX_RB(dst, src);
530 EmitUint8(0x0F); 476 EmitUint8(0x0F);
531 EmitUint8(0x6E); 477 EmitUint8(0x6E);
532 EmitOperand(dst & 7, Operand(src)); 478 EmitOperand(dst & 7, Operand(src));
533 } 479 }
534 480
535
536 void Assembler::movd(Register dst, XmmRegister src) { 481 void Assembler::movd(Register dst, XmmRegister src) {
537 ASSERT(src <= XMM15); 482 ASSERT(src <= XMM15);
538 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 483 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
539 EmitUint8(0x66); 484 EmitUint8(0x66);
540 EmitREX_RB(src, dst); 485 EmitREX_RB(src, dst);
541 EmitUint8(0x0F); 486 EmitUint8(0x0F);
542 EmitUint8(0x7E); 487 EmitUint8(0x7E);
543 EmitOperand(src & 7, Operand(dst)); 488 EmitOperand(src & 7, Operand(dst));
544 } 489 }
545 490
546
547 void Assembler::addss(XmmRegister dst, XmmRegister src) { 491 void Assembler::addss(XmmRegister dst, XmmRegister src) {
548 ASSERT(src <= XMM15); 492 ASSERT(src <= XMM15);
549 ASSERT(dst <= XMM15); 493 ASSERT(dst <= XMM15);
550 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 494 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
551 EmitUint8(0xF3); 495 EmitUint8(0xF3);
552 EmitREX_RB(dst, src); 496 EmitREX_RB(dst, src);
553 EmitUint8(0x0F); 497 EmitUint8(0x0F);
554 EmitUint8(0x58); 498 EmitUint8(0x58);
555 EmitXmmRegisterOperand(dst & 7, src); 499 EmitXmmRegisterOperand(dst & 7, src);
556 } 500 }
557 501
558
559 void Assembler::subss(XmmRegister dst, XmmRegister src) { 502 void Assembler::subss(XmmRegister dst, XmmRegister src) {
560 ASSERT(src <= XMM15); 503 ASSERT(src <= XMM15);
561 ASSERT(dst <= XMM15); 504 ASSERT(dst <= XMM15);
562 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 505 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
563 EmitUint8(0xF3); 506 EmitUint8(0xF3);
564 EmitREX_RB(dst, src); 507 EmitREX_RB(dst, src);
565 EmitUint8(0x0F); 508 EmitUint8(0x0F);
566 EmitUint8(0x5C); 509 EmitUint8(0x5C);
567 EmitXmmRegisterOperand(dst & 7, src); 510 EmitXmmRegisterOperand(dst & 7, src);
568 } 511 }
569 512
570
571 void Assembler::mulss(XmmRegister dst, XmmRegister src) { 513 void Assembler::mulss(XmmRegister dst, XmmRegister src) {
572 ASSERT(src <= XMM15); 514 ASSERT(src <= XMM15);
573 ASSERT(dst <= XMM15); 515 ASSERT(dst <= XMM15);
574 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 516 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
575 EmitUint8(0xF3); 517 EmitUint8(0xF3);
576 EmitREX_RB(dst, src); 518 EmitREX_RB(dst, src);
577 EmitUint8(0x0F); 519 EmitUint8(0x0F);
578 EmitUint8(0x59); 520 EmitUint8(0x59);
579 EmitXmmRegisterOperand(dst & 7, src); 521 EmitXmmRegisterOperand(dst & 7, src);
580 } 522 }
581 523
582
583 void Assembler::divss(XmmRegister dst, XmmRegister src) { 524 void Assembler::divss(XmmRegister dst, XmmRegister src) {
584 ASSERT(src <= XMM15); 525 ASSERT(src <= XMM15);
585 ASSERT(dst <= XMM15); 526 ASSERT(dst <= XMM15);
586 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 527 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
587 EmitUint8(0xF3); 528 EmitUint8(0xF3);
588 EmitREX_RB(dst, src); 529 EmitREX_RB(dst, src);
589 EmitUint8(0x0F); 530 EmitUint8(0x0F);
590 EmitUint8(0x5E); 531 EmitUint8(0x5E);
591 EmitXmmRegisterOperand(dst & 7, src); 532 EmitXmmRegisterOperand(dst & 7, src);
592 } 533 }
593 534
594
595 void Assembler::movsd(XmmRegister dst, const Address& src) { 535 void Assembler::movsd(XmmRegister dst, const Address& src) {
596 ASSERT(dst <= XMM15); 536 ASSERT(dst <= XMM15);
597 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 537 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
598 EmitUint8(0xF2); 538 EmitUint8(0xF2);
599 EmitREX_RB(dst, src); 539 EmitREX_RB(dst, src);
600 EmitUint8(0x0F); 540 EmitUint8(0x0F);
601 EmitUint8(0x10); 541 EmitUint8(0x10);
602 EmitOperand(dst & 7, src); 542 EmitOperand(dst & 7, src);
603 } 543 }
604 544
605
606 void Assembler::movsd(const Address& dst, XmmRegister src) { 545 void Assembler::movsd(const Address& dst, XmmRegister src) {
607 ASSERT(src <= XMM15); 546 ASSERT(src <= XMM15);
608 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 547 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
609 EmitUint8(0xF2); 548 EmitUint8(0xF2);
610 EmitREX_RB(src, dst); 549 EmitREX_RB(src, dst);
611 EmitUint8(0x0F); 550 EmitUint8(0x0F);
612 EmitUint8(0x11); 551 EmitUint8(0x11);
613 EmitOperand(src & 7, dst); 552 EmitOperand(src & 7, dst);
614 } 553 }
615 554
616
617 void Assembler::movsd(XmmRegister dst, XmmRegister src) { 555 void Assembler::movsd(XmmRegister dst, XmmRegister src) {
618 ASSERT(src <= XMM15); 556 ASSERT(src <= XMM15);
619 ASSERT(dst <= XMM15); 557 ASSERT(dst <= XMM15);
620 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 558 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
621 EmitUint8(0xF2); 559 EmitUint8(0xF2);
622 EmitREX_RB(src, dst); 560 EmitREX_RB(src, dst);
623 EmitUint8(0x0F); 561 EmitUint8(0x0F);
624 EmitUint8(0x11); 562 EmitUint8(0x11);
625 EmitXmmRegisterOperand(src & 7, dst); 563 EmitXmmRegisterOperand(src & 7, dst);
626 } 564 }
627 565
628
629 void Assembler::movaps(XmmRegister dst, XmmRegister src) { 566 void Assembler::movaps(XmmRegister dst, XmmRegister src) {
630 ASSERT(src <= XMM15); 567 ASSERT(src <= XMM15);
631 ASSERT(dst <= XMM15); 568 ASSERT(dst <= XMM15);
632 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 569 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
633 EmitREX_RB(dst, src); 570 EmitREX_RB(dst, src);
634 EmitUint8(0x0F); 571 EmitUint8(0x0F);
635 EmitUint8(0x28); 572 EmitUint8(0x28);
636 EmitXmmRegisterOperand(dst & 7, src); 573 EmitXmmRegisterOperand(dst & 7, src);
637 } 574 }
638 575
639
640 void Assembler::movups(XmmRegister dst, const Address& src) { 576 void Assembler::movups(XmmRegister dst, const Address& src) {
641 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 577 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
642 EmitREX_RB(dst, src); 578 EmitREX_RB(dst, src);
643 EmitUint8(0x0F); 579 EmitUint8(0x0F);
644 EmitUint8(0x10); 580 EmitUint8(0x10);
645 EmitOperand(dst & 7, src); 581 EmitOperand(dst & 7, src);
646 } 582 }
647 583
648
649 void Assembler::movups(const Address& dst, XmmRegister src) { 584 void Assembler::movups(const Address& dst, XmmRegister src) {
650 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 585 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
651 EmitREX_RB(src, dst); 586 EmitREX_RB(src, dst);
652 EmitUint8(0x0F); 587 EmitUint8(0x0F);
653 EmitUint8(0x11); 588 EmitUint8(0x11);
654 EmitOperand(src & 7, dst); 589 EmitOperand(src & 7, dst);
655 } 590 }
656 591
657
658 void Assembler::addsd(XmmRegister dst, XmmRegister src) { 592 void Assembler::addsd(XmmRegister dst, XmmRegister src) {
659 ASSERT(src <= XMM15); 593 ASSERT(src <= XMM15);
660 ASSERT(dst <= XMM15); 594 ASSERT(dst <= XMM15);
661 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 595 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
662 EmitUint8(0xF2); 596 EmitUint8(0xF2);
663 EmitREX_RB(dst, src); 597 EmitREX_RB(dst, src);
664 EmitUint8(0x0F); 598 EmitUint8(0x0F);
665 EmitUint8(0x58); 599 EmitUint8(0x58);
666 EmitXmmRegisterOperand(dst & 7, src); 600 EmitXmmRegisterOperand(dst & 7, src);
667 } 601 }
668 602
669
670 void Assembler::subsd(XmmRegister dst, XmmRegister src) { 603 void Assembler::subsd(XmmRegister dst, XmmRegister src) {
671 ASSERT(src <= XMM15); 604 ASSERT(src <= XMM15);
672 ASSERT(dst <= XMM15); 605 ASSERT(dst <= XMM15);
673 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 606 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
674 EmitUint8(0xF2); 607 EmitUint8(0xF2);
675 EmitREX_RB(dst, src); 608 EmitREX_RB(dst, src);
676 EmitUint8(0x0F); 609 EmitUint8(0x0F);
677 EmitUint8(0x5C); 610 EmitUint8(0x5C);
678 EmitXmmRegisterOperand(dst & 7, src); 611 EmitXmmRegisterOperand(dst & 7, src);
679 } 612 }
680 613
681
682 void Assembler::mulsd(XmmRegister dst, XmmRegister src) { 614 void Assembler::mulsd(XmmRegister dst, XmmRegister src) {
683 ASSERT(src <= XMM15); 615 ASSERT(src <= XMM15);
684 ASSERT(dst <= XMM15); 616 ASSERT(dst <= XMM15);
685 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 617 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
686 EmitUint8(0xF2); 618 EmitUint8(0xF2);
687 EmitREX_RB(dst, src); 619 EmitREX_RB(dst, src);
688 EmitUint8(0x0F); 620 EmitUint8(0x0F);
689 EmitUint8(0x59); 621 EmitUint8(0x59);
690 EmitXmmRegisterOperand(dst & 7, src); 622 EmitXmmRegisterOperand(dst & 7, src);
691 } 623 }
692 624
693
694 void Assembler::divsd(XmmRegister dst, XmmRegister src) { 625 void Assembler::divsd(XmmRegister dst, XmmRegister src) {
695 ASSERT(src <= XMM15); 626 ASSERT(src <= XMM15);
696 ASSERT(dst <= XMM15); 627 ASSERT(dst <= XMM15);
697 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 628 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
698 EmitUint8(0xF2); 629 EmitUint8(0xF2);
699 EmitREX_RB(dst, src); 630 EmitREX_RB(dst, src);
700 EmitUint8(0x0F); 631 EmitUint8(0x0F);
701 EmitUint8(0x5E); 632 EmitUint8(0x5E);
702 EmitXmmRegisterOperand(dst & 7, src); 633 EmitXmmRegisterOperand(dst & 7, src);
703 } 634 }
704 635
705
706 void Assembler::addpl(XmmRegister dst, XmmRegister src) { 636 void Assembler::addpl(XmmRegister dst, XmmRegister src) {
707 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 637 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
708 EmitUint8(0x66); 638 EmitUint8(0x66);
709 EmitREX_RB(dst, src); 639 EmitREX_RB(dst, src);
710 EmitUint8(0x0F); 640 EmitUint8(0x0F);
711 EmitUint8(0xFE); 641 EmitUint8(0xFE);
712 EmitXmmRegisterOperand(dst & 7, src); 642 EmitXmmRegisterOperand(dst & 7, src);
713 } 643 }
714 644
715
716 void Assembler::subpl(XmmRegister dst, XmmRegister src) { 645 void Assembler::subpl(XmmRegister dst, XmmRegister src) {
717 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 646 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
718 EmitUint8(0x66); 647 EmitUint8(0x66);
719 EmitREX_RB(dst, src); 648 EmitREX_RB(dst, src);
720 EmitUint8(0x0F); 649 EmitUint8(0x0F);
721 EmitUint8(0xFA); 650 EmitUint8(0xFA);
722 EmitXmmRegisterOperand(dst & 7, src); 651 EmitXmmRegisterOperand(dst & 7, src);
723 } 652 }
724 653
725
726 void Assembler::addps(XmmRegister dst, XmmRegister src) { 654 void Assembler::addps(XmmRegister dst, XmmRegister src) {
727 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 655 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
728 EmitREX_RB(dst, src); 656 EmitREX_RB(dst, src);
729 EmitUint8(0x0F); 657 EmitUint8(0x0F);
730 EmitUint8(0x58); 658 EmitUint8(0x58);
731 EmitXmmRegisterOperand(dst & 7, src); 659 EmitXmmRegisterOperand(dst & 7, src);
732 } 660 }
733 661
734
735 void Assembler::subps(XmmRegister dst, XmmRegister src) { 662 void Assembler::subps(XmmRegister dst, XmmRegister src) {
736 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 663 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
737 EmitREX_RB(dst, src); 664 EmitREX_RB(dst, src);
738 EmitUint8(0x0F); 665 EmitUint8(0x0F);
739 EmitUint8(0x5C); 666 EmitUint8(0x5C);
740 EmitXmmRegisterOperand(dst & 7, src); 667 EmitXmmRegisterOperand(dst & 7, src);
741 } 668 }
742 669
743
744 void Assembler::divps(XmmRegister dst, XmmRegister src) { 670 void Assembler::divps(XmmRegister dst, XmmRegister src) {
745 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 671 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
746 EmitREX_RB(dst, src); 672 EmitREX_RB(dst, src);
747 EmitUint8(0x0F); 673 EmitUint8(0x0F);
748 EmitUint8(0x5E); 674 EmitUint8(0x5E);
749 EmitXmmRegisterOperand(dst & 7, src); 675 EmitXmmRegisterOperand(dst & 7, src);
750 } 676 }
751 677
752
753 void Assembler::mulps(XmmRegister dst, XmmRegister src) { 678 void Assembler::mulps(XmmRegister dst, XmmRegister src) {
754 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 679 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
755 EmitREX_RB(dst, src); 680 EmitREX_RB(dst, src);
756 EmitUint8(0x0F); 681 EmitUint8(0x0F);
757 EmitUint8(0x59); 682 EmitUint8(0x59);
758 EmitXmmRegisterOperand(dst & 7, src); 683 EmitXmmRegisterOperand(dst & 7, src);
759 } 684 }
760 685
761
762 void Assembler::minps(XmmRegister dst, XmmRegister src) { 686 void Assembler::minps(XmmRegister dst, XmmRegister src) {
763 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 687 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
764 EmitREX_RB(dst, src); 688 EmitREX_RB(dst, src);
765 EmitUint8(0x0F); 689 EmitUint8(0x0F);
766 EmitUint8(0x5D); 690 EmitUint8(0x5D);
767 EmitXmmRegisterOperand(dst & 7, src); 691 EmitXmmRegisterOperand(dst & 7, src);
768 } 692 }
769 693
770
771 void Assembler::maxps(XmmRegister dst, XmmRegister src) { 694 void Assembler::maxps(XmmRegister dst, XmmRegister src) {
772 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 695 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
773 EmitREX_RB(dst, src); 696 EmitREX_RB(dst, src);
774 EmitUint8(0x0F); 697 EmitUint8(0x0F);
775 EmitUint8(0x5F); 698 EmitUint8(0x5F);
776 EmitXmmRegisterOperand(dst & 7, src); 699 EmitXmmRegisterOperand(dst & 7, src);
777 } 700 }
778 701
779
780 void Assembler::andps(XmmRegister dst, XmmRegister src) { 702 void Assembler::andps(XmmRegister dst, XmmRegister src) {
781 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 703 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
782 EmitREX_RB(dst, src); 704 EmitREX_RB(dst, src);
783 EmitUint8(0x0F); 705 EmitUint8(0x0F);
784 EmitUint8(0x54); 706 EmitUint8(0x54);
785 EmitXmmRegisterOperand(dst & 7, src); 707 EmitXmmRegisterOperand(dst & 7, src);
786 } 708 }
787 709
788
789 void Assembler::andps(XmmRegister dst, const Address& src) { 710 void Assembler::andps(XmmRegister dst, const Address& src) {
790 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 711 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
791 EmitREX_RB(dst, src); 712 EmitREX_RB(dst, src);
792 EmitUint8(0x0F); 713 EmitUint8(0x0F);
793 EmitUint8(0x54); 714 EmitUint8(0x54);
794 EmitOperand(dst & 7, src); 715 EmitOperand(dst & 7, src);
795 } 716 }
796 717
797
798 void Assembler::orps(XmmRegister dst, XmmRegister src) { 718 void Assembler::orps(XmmRegister dst, XmmRegister src) {
799 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 719 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
800 EmitREX_RB(dst, src); 720 EmitREX_RB(dst, src);
801 EmitUint8(0x0F); 721 EmitUint8(0x0F);
802 EmitUint8(0x56); 722 EmitUint8(0x56);
803 EmitXmmRegisterOperand(dst & 7, src); 723 EmitXmmRegisterOperand(dst & 7, src);
804 } 724 }
805 725
806 void Assembler::notps(XmmRegister dst) { 726 void Assembler::notps(XmmRegister dst) {
807 // { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; 727 // { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
808 movq(TMP, Address(THR, Thread::float_not_address_offset())); 728 movq(TMP, Address(THR, Thread::float_not_address_offset()));
809 xorps(dst, Address(TMP, 0)); 729 xorps(dst, Address(TMP, 0));
810 } 730 }
811 731
812
813 void Assembler::negateps(XmmRegister dst) { 732 void Assembler::negateps(XmmRegister dst) {
814 // { 0x80000000, 0x80000000, 0x80000000, 0x80000000 } 733 // { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }
815 movq(TMP, Address(THR, Thread::float_negate_address_offset())); 734 movq(TMP, Address(THR, Thread::float_negate_address_offset()));
816 xorps(dst, Address(TMP, 0)); 735 xorps(dst, Address(TMP, 0));
817 } 736 }
818 737
819
820 void Assembler::absps(XmmRegister dst) { 738 void Assembler::absps(XmmRegister dst) {
821 // { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF } 739 // { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }
822 movq(TMP, Address(THR, Thread::float_absolute_address_offset())); 740 movq(TMP, Address(THR, Thread::float_absolute_address_offset()));
823 andps(dst, Address(TMP, 0)); 741 andps(dst, Address(TMP, 0));
824 } 742 }
825 743
826
827 void Assembler::zerowps(XmmRegister dst) { 744 void Assembler::zerowps(XmmRegister dst) {
828 // { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 } 745 // { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }
829 movq(TMP, Address(THR, Thread::float_zerow_address_offset())); 746 movq(TMP, Address(THR, Thread::float_zerow_address_offset()));
830 andps(dst, Address(TMP, 0)); 747 andps(dst, Address(TMP, 0));
831 } 748 }
832 749
833
834 void Assembler::cmppseq(XmmRegister dst, XmmRegister src) { 750 void Assembler::cmppseq(XmmRegister dst, XmmRegister src) {
835 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 751 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
836 EmitREX_RB(dst, src); 752 EmitREX_RB(dst, src);
837 EmitUint8(0x0F); 753 EmitUint8(0x0F);
838 EmitUint8(0xC2); 754 EmitUint8(0xC2);
839 EmitXmmRegisterOperand(dst & 7, src); 755 EmitXmmRegisterOperand(dst & 7, src);
840 EmitUint8(0x0); 756 EmitUint8(0x0);
841 } 757 }
842 758
843
844 void Assembler::cmppsneq(XmmRegister dst, XmmRegister src) { 759 void Assembler::cmppsneq(XmmRegister dst, XmmRegister src) {
845 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 760 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
846 EmitREX_RB(dst, src); 761 EmitREX_RB(dst, src);
847 EmitUint8(0x0F); 762 EmitUint8(0x0F);
848 EmitUint8(0xC2); 763 EmitUint8(0xC2);
849 EmitXmmRegisterOperand(dst & 7, src); 764 EmitXmmRegisterOperand(dst & 7, src);
850 EmitUint8(0x4); 765 EmitUint8(0x4);
851 } 766 }
852 767
853
854 void Assembler::cmppslt(XmmRegister dst, XmmRegister src) { 768 void Assembler::cmppslt(XmmRegister dst, XmmRegister src) {
855 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 769 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
856 EmitREX_RB(dst, src); 770 EmitREX_RB(dst, src);
857 EmitUint8(0x0F); 771 EmitUint8(0x0F);
858 EmitUint8(0xC2); 772 EmitUint8(0xC2);
859 EmitXmmRegisterOperand(dst & 7, src); 773 EmitXmmRegisterOperand(dst & 7, src);
860 EmitUint8(0x1); 774 EmitUint8(0x1);
861 } 775 }
862 776
863
864 void Assembler::cmppsle(XmmRegister dst, XmmRegister src) { 777 void Assembler::cmppsle(XmmRegister dst, XmmRegister src) {
865 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 778 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
866 EmitREX_RB(dst, src); 779 EmitREX_RB(dst, src);
867 EmitUint8(0x0F); 780 EmitUint8(0x0F);
868 EmitUint8(0xC2); 781 EmitUint8(0xC2);
869 EmitXmmRegisterOperand(dst & 7, src); 782 EmitXmmRegisterOperand(dst & 7, src);
870 EmitUint8(0x2); 783 EmitUint8(0x2);
871 } 784 }
872 785
873
874 void Assembler::cmppsnlt(XmmRegister dst, XmmRegister src) { 786 void Assembler::cmppsnlt(XmmRegister dst, XmmRegister src) {
875 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 787 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
876 EmitREX_RB(dst, src); 788 EmitREX_RB(dst, src);
877 EmitUint8(0x0F); 789 EmitUint8(0x0F);
878 EmitUint8(0xC2); 790 EmitUint8(0xC2);
879 EmitXmmRegisterOperand(dst & 7, src); 791 EmitXmmRegisterOperand(dst & 7, src);
880 EmitUint8(0x5); 792 EmitUint8(0x5);
881 } 793 }
882 794
883
884 void Assembler::cmppsnle(XmmRegister dst, XmmRegister src) { 795 void Assembler::cmppsnle(XmmRegister dst, XmmRegister src) {
885 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 796 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
886 EmitREX_RB(dst, src); 797 EmitREX_RB(dst, src);
887 EmitUint8(0x0F); 798 EmitUint8(0x0F);
888 EmitUint8(0xC2); 799 EmitUint8(0xC2);
889 EmitXmmRegisterOperand(dst & 7, src); 800 EmitXmmRegisterOperand(dst & 7, src);
890 EmitUint8(0x6); 801 EmitUint8(0x6);
891 } 802 }
892 803
893
894 void Assembler::sqrtps(XmmRegister dst) { 804 void Assembler::sqrtps(XmmRegister dst) {
895 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 805 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
896 EmitREX_RB(dst, dst); 806 EmitREX_RB(dst, dst);
897 EmitUint8(0x0F); 807 EmitUint8(0x0F);
898 EmitUint8(0x51); 808 EmitUint8(0x51);
899 EmitXmmRegisterOperand(dst & 7, dst); 809 EmitXmmRegisterOperand(dst & 7, dst);
900 } 810 }
901 811
902
903 void Assembler::rsqrtps(XmmRegister dst) { 812 void Assembler::rsqrtps(XmmRegister dst) {
904 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 813 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
905 EmitREX_RB(dst, dst); 814 EmitREX_RB(dst, dst);
906 EmitUint8(0x0F); 815 EmitUint8(0x0F);
907 EmitUint8(0x52); 816 EmitUint8(0x52);
908 EmitXmmRegisterOperand(dst & 7, dst); 817 EmitXmmRegisterOperand(dst & 7, dst);
909 } 818 }
910 819
911
912 void Assembler::reciprocalps(XmmRegister dst) { 820 void Assembler::reciprocalps(XmmRegister dst) {
913 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 821 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
914 EmitREX_RB(dst, dst); 822 EmitREX_RB(dst, dst);
915 EmitUint8(0x0F); 823 EmitUint8(0x0F);
916 EmitUint8(0x53); 824 EmitUint8(0x53);
917 EmitXmmRegisterOperand(dst & 7, dst); 825 EmitXmmRegisterOperand(dst & 7, dst);
918 } 826 }
919 827
920
921 void Assembler::movhlps(XmmRegister dst, XmmRegister src) { 828 void Assembler::movhlps(XmmRegister dst, XmmRegister src) {
922 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 829 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
923 EmitREX_RB(dst, src); 830 EmitREX_RB(dst, src);
924 EmitUint8(0x0F); 831 EmitUint8(0x0F);
925 EmitUint8(0x12); 832 EmitUint8(0x12);
926 EmitXmmRegisterOperand(dst & 7, src); 833 EmitXmmRegisterOperand(dst & 7, src);
927 } 834 }
928 835
929
930 void Assembler::movlhps(XmmRegister dst, XmmRegister src) { 836 void Assembler::movlhps(XmmRegister dst, XmmRegister src) {
931 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 837 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
932 EmitREX_RB(dst, src); 838 EmitREX_RB(dst, src);
933 EmitUint8(0x0F); 839 EmitUint8(0x0F);
934 EmitUint8(0x16); 840 EmitUint8(0x16);
935 EmitXmmRegisterOperand(dst & 7, src); 841 EmitXmmRegisterOperand(dst & 7, src);
936 } 842 }
937 843
938
939 void Assembler::unpcklps(XmmRegister dst, XmmRegister src) { 844 void Assembler::unpcklps(XmmRegister dst, XmmRegister src) {
940 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 845 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
941 EmitREX_RB(dst, src); 846 EmitREX_RB(dst, src);
942 EmitUint8(0x0F); 847 EmitUint8(0x0F);
943 EmitUint8(0x14); 848 EmitUint8(0x14);
944 EmitXmmRegisterOperand(dst & 7, src); 849 EmitXmmRegisterOperand(dst & 7, src);
945 } 850 }
946 851
947
948 void Assembler::unpckhps(XmmRegister dst, XmmRegister src) { 852 void Assembler::unpckhps(XmmRegister dst, XmmRegister src) {
949 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 853 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
950 EmitREX_RB(dst, src); 854 EmitREX_RB(dst, src);
951 EmitUint8(0x0F); 855 EmitUint8(0x0F);
952 EmitUint8(0x15); 856 EmitUint8(0x15);
953 EmitXmmRegisterOperand(dst & 7, src); 857 EmitXmmRegisterOperand(dst & 7, src);
954 } 858 }
955 859
956
957 void Assembler::unpcklpd(XmmRegister dst, XmmRegister src) { 860 void Assembler::unpcklpd(XmmRegister dst, XmmRegister src) {
958 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 861 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
959 EmitUint8(0x66); 862 EmitUint8(0x66);
960 EmitREX_RB(dst, src); 863 EmitREX_RB(dst, src);
961 EmitUint8(0x0F); 864 EmitUint8(0x0F);
962 EmitUint8(0x14); 865 EmitUint8(0x14);
963 EmitXmmRegisterOperand(dst & 7, src); 866 EmitXmmRegisterOperand(dst & 7, src);
964 } 867 }
965 868
966
967 void Assembler::unpckhpd(XmmRegister dst, XmmRegister src) { 869 void Assembler::unpckhpd(XmmRegister dst, XmmRegister src) {
968 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 870 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
969 EmitUint8(0x66); 871 EmitUint8(0x66);
970 EmitREX_RB(dst, src); 872 EmitREX_RB(dst, src);
971 EmitUint8(0x0F); 873 EmitUint8(0x0F);
972 EmitUint8(0x15); 874 EmitUint8(0x15);
973 EmitXmmRegisterOperand(dst & 7, src); 875 EmitXmmRegisterOperand(dst & 7, src);
974 } 876 }
975 877
976
977 void Assembler::set1ps(XmmRegister dst, Register tmp1, const Immediate& imm) { 878 void Assembler::set1ps(XmmRegister dst, Register tmp1, const Immediate& imm) {
978 // Load 32-bit immediate value into tmp1. 879 // Load 32-bit immediate value into tmp1.
979 movl(tmp1, imm); 880 movl(tmp1, imm);
980 // Move value from tmp1 into dst. 881 // Move value from tmp1 into dst.
981 movd(dst, tmp1); 882 movd(dst, tmp1);
982 // Broadcast low lane into other three lanes. 883 // Broadcast low lane into other three lanes.
983 shufps(dst, dst, Immediate(0x0)); 884 shufps(dst, dst, Immediate(0x0));
984 } 885 }
985 886
986
987 void Assembler::shufps(XmmRegister dst, XmmRegister src, const Immediate& imm) { 887 void Assembler::shufps(XmmRegister dst, XmmRegister src, const Immediate& imm) {
988 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 888 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
989 EmitREX_RB(dst, src); 889 EmitREX_RB(dst, src);
990 EmitUint8(0x0F); 890 EmitUint8(0x0F);
991 EmitUint8(0xC6); 891 EmitUint8(0xC6);
992 EmitXmmRegisterOperand(dst & 7, src); 892 EmitXmmRegisterOperand(dst & 7, src);
993 ASSERT(imm.is_uint8()); 893 ASSERT(imm.is_uint8());
994 EmitUint8(imm.value()); 894 EmitUint8(imm.value());
995 } 895 }
996 896
997
998 void Assembler::addpd(XmmRegister dst, XmmRegister src) { 897 void Assembler::addpd(XmmRegister dst, XmmRegister src) {
999 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 898 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1000 ASSERT(src <= XMM15); 899 ASSERT(src <= XMM15);
1001 ASSERT(dst <= XMM15); 900 ASSERT(dst <= XMM15);
1002 EmitUint8(0x66); 901 EmitUint8(0x66);
1003 EmitREX_RB(dst, src); 902 EmitREX_RB(dst, src);
1004 EmitUint8(0x0F); 903 EmitUint8(0x0F);
1005 EmitUint8(0x58); 904 EmitUint8(0x58);
1006 EmitXmmRegisterOperand(dst & 7, src); 905 EmitXmmRegisterOperand(dst & 7, src);
1007 } 906 }
1008 907
1009
1010 void Assembler::negatepd(XmmRegister dst) { 908 void Assembler::negatepd(XmmRegister dst) {
1011 // { 0x8000000000000000LL, 0x8000000000000000LL } 909 // { 0x8000000000000000LL, 0x8000000000000000LL }
1012 movq(TMP, Address(THR, Thread::double_negate_address_offset())); 910 movq(TMP, Address(THR, Thread::double_negate_address_offset()));
1013 xorpd(dst, Address(TMP, 0)); 911 xorpd(dst, Address(TMP, 0));
1014 } 912 }
1015 913
1016
1017 void Assembler::subpd(XmmRegister dst, XmmRegister src) { 914 void Assembler::subpd(XmmRegister dst, XmmRegister src) {
1018 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 915 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1019 ASSERT(src <= XMM15); 916 ASSERT(src <= XMM15);
1020 ASSERT(dst <= XMM15); 917 ASSERT(dst <= XMM15);
1021 EmitUint8(0x66); 918 EmitUint8(0x66);
1022 EmitREX_RB(dst, src); 919 EmitREX_RB(dst, src);
1023 EmitUint8(0x0F); 920 EmitUint8(0x0F);
1024 EmitUint8(0x5C); 921 EmitUint8(0x5C);
1025 EmitXmmRegisterOperand(dst & 7, src); 922 EmitXmmRegisterOperand(dst & 7, src);
1026 } 923 }
1027 924
1028
1029 void Assembler::mulpd(XmmRegister dst, XmmRegister src) { 925 void Assembler::mulpd(XmmRegister dst, XmmRegister src) {
1030 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 926 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1031 ASSERT(src <= XMM15); 927 ASSERT(src <= XMM15);
1032 ASSERT(dst <= XMM15); 928 ASSERT(dst <= XMM15);
1033 EmitUint8(0x66); 929 EmitUint8(0x66);
1034 EmitREX_RB(dst, src); 930 EmitREX_RB(dst, src);
1035 EmitUint8(0x0F); 931 EmitUint8(0x0F);
1036 EmitUint8(0x59); 932 EmitUint8(0x59);
1037 EmitXmmRegisterOperand(dst & 7, src); 933 EmitXmmRegisterOperand(dst & 7, src);
1038 } 934 }
1039 935
1040
1041 void Assembler::divpd(XmmRegister dst, XmmRegister src) { 936 void Assembler::divpd(XmmRegister dst, XmmRegister src) {
1042 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 937 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1043 ASSERT(src <= XMM15); 938 ASSERT(src <= XMM15);
1044 ASSERT(dst <= XMM15); 939 ASSERT(dst <= XMM15);
1045 EmitUint8(0x66); 940 EmitUint8(0x66);
1046 EmitREX_RB(dst, src); 941 EmitREX_RB(dst, src);
1047 EmitUint8(0x0F); 942 EmitUint8(0x0F);
1048 EmitUint8(0x5E); 943 EmitUint8(0x5E);
1049 EmitXmmRegisterOperand(dst & 7, src); 944 EmitXmmRegisterOperand(dst & 7, src);
1050 } 945 }
1051 946
1052
1053 void Assembler::abspd(XmmRegister dst) { 947 void Assembler::abspd(XmmRegister dst) {
1054 // { 0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL } 948 // { 0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL }
1055 movq(TMP, Address(THR, Thread::double_abs_address_offset())); 949 movq(TMP, Address(THR, Thread::double_abs_address_offset()));
1056 andpd(dst, Address(TMP, 0)); 950 andpd(dst, Address(TMP, 0));
1057 } 951 }
1058 952
1059
1060 void Assembler::minpd(XmmRegister dst, XmmRegister src) { 953 void Assembler::minpd(XmmRegister dst, XmmRegister src) {
1061 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 954 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1062 ASSERT(src <= XMM15); 955 ASSERT(src <= XMM15);
1063 ASSERT(dst <= XMM15); 956 ASSERT(dst <= XMM15);
1064 EmitUint8(0x66); 957 EmitUint8(0x66);
1065 EmitREX_RB(dst, src); 958 EmitREX_RB(dst, src);
1066 EmitUint8(0x0F); 959 EmitUint8(0x0F);
1067 EmitUint8(0x5D); 960 EmitUint8(0x5D);
1068 EmitXmmRegisterOperand(dst & 7, src); 961 EmitXmmRegisterOperand(dst & 7, src);
1069 } 962 }
1070 963
1071
1072 void Assembler::maxpd(XmmRegister dst, XmmRegister src) { 964 void Assembler::maxpd(XmmRegister dst, XmmRegister src) {
1073 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 965 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1074 ASSERT(src <= XMM15); 966 ASSERT(src <= XMM15);
1075 ASSERT(dst <= XMM15); 967 ASSERT(dst <= XMM15);
1076 EmitUint8(0x66); 968 EmitUint8(0x66);
1077 EmitREX_RB(dst, src); 969 EmitREX_RB(dst, src);
1078 EmitUint8(0x0F); 970 EmitUint8(0x0F);
1079 EmitUint8(0x5F); 971 EmitUint8(0x5F);
1080 EmitXmmRegisterOperand(dst & 7, src); 972 EmitXmmRegisterOperand(dst & 7, src);
1081 } 973 }
1082 974
1083
1084 void Assembler::sqrtpd(XmmRegister dst) { 975 void Assembler::sqrtpd(XmmRegister dst) {
1085 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 976 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1086 ASSERT(dst <= XMM15); 977 ASSERT(dst <= XMM15);
1087 EmitUint8(0x66); 978 EmitUint8(0x66);
1088 EmitREX_RB(dst, dst); 979 EmitREX_RB(dst, dst);
1089 EmitUint8(0x0F); 980 EmitUint8(0x0F);
1090 EmitUint8(0x51); 981 EmitUint8(0x51);
1091 EmitXmmRegisterOperand(dst & 7, dst); 982 EmitXmmRegisterOperand(dst & 7, dst);
1092 } 983 }
1093 984
1094
1095 void Assembler::cvtps2pd(XmmRegister dst, XmmRegister src) { 985 void Assembler::cvtps2pd(XmmRegister dst, XmmRegister src) {
1096 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 986 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1097 ASSERT(src <= XMM15); 987 ASSERT(src <= XMM15);
1098 ASSERT(dst <= XMM15); 988 ASSERT(dst <= XMM15);
1099 EmitREX_RB(dst, src); 989 EmitREX_RB(dst, src);
1100 EmitUint8(0x0F); 990 EmitUint8(0x0F);
1101 EmitUint8(0x5A); 991 EmitUint8(0x5A);
1102 EmitXmmRegisterOperand(dst & 7, src); 992 EmitXmmRegisterOperand(dst & 7, src);
1103 } 993 }
1104 994
1105
1106 void Assembler::cvtpd2ps(XmmRegister dst, XmmRegister src) { 995 void Assembler::cvtpd2ps(XmmRegister dst, XmmRegister src) {
1107 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 996 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1108 ASSERT(src <= XMM15); 997 ASSERT(src <= XMM15);
1109 ASSERT(dst <= XMM15); 998 ASSERT(dst <= XMM15);
1110 EmitUint8(0x66); 999 EmitUint8(0x66);
1111 EmitREX_RB(dst, src); 1000 EmitREX_RB(dst, src);
1112 EmitUint8(0x0F); 1001 EmitUint8(0x0F);
1113 EmitUint8(0x5A); 1002 EmitUint8(0x5A);
1114 EmitXmmRegisterOperand(dst & 7, src); 1003 EmitXmmRegisterOperand(dst & 7, src);
1115 } 1004 }
1116 1005
1117
1118 void Assembler::shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm) { 1006 void Assembler::shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm) {
1119 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1007 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1120 EmitUint8(0x66); 1008 EmitUint8(0x66);
1121 EmitREX_RB(dst, src); 1009 EmitREX_RB(dst, src);
1122 EmitUint8(0x0F); 1010 EmitUint8(0x0F);
1123 EmitUint8(0xC6); 1011 EmitUint8(0xC6);
1124 EmitXmmRegisterOperand(dst & 7, src); 1012 EmitXmmRegisterOperand(dst & 7, src);
1125 ASSERT(imm.is_uint8()); 1013 ASSERT(imm.is_uint8());
1126 EmitUint8(imm.value()); 1014 EmitUint8(imm.value());
1127 } 1015 }
1128 1016
1129
1130 void Assembler::comisd(XmmRegister a, XmmRegister b) { 1017 void Assembler::comisd(XmmRegister a, XmmRegister b) {
1131 ASSERT(a <= XMM15); 1018 ASSERT(a <= XMM15);
1132 ASSERT(b <= XMM15); 1019 ASSERT(b <= XMM15);
1133 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1020 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1134 EmitUint8(0x66); 1021 EmitUint8(0x66);
1135 EmitREX_RB(a, b); 1022 EmitREX_RB(a, b);
1136 EmitUint8(0x0F); 1023 EmitUint8(0x0F);
1137 EmitUint8(0x2F); 1024 EmitUint8(0x2F);
1138 EmitXmmRegisterOperand(a & 7, b); 1025 EmitXmmRegisterOperand(a & 7, b);
1139 } 1026 }
1140 1027
1141
1142 void Assembler::movmskpd(Register dst, XmmRegister src) { 1028 void Assembler::movmskpd(Register dst, XmmRegister src) {
1143 ASSERT(src <= XMM15); 1029 ASSERT(src <= XMM15);
1144 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1030 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1145 EmitUint8(0x66); 1031 EmitUint8(0x66);
1146 EmitREX_RB(dst, src); 1032 EmitREX_RB(dst, src);
1147 EmitUint8(0x0F); 1033 EmitUint8(0x0F);
1148 EmitUint8(0x50); 1034 EmitUint8(0x50);
1149 EmitXmmRegisterOperand(dst & 7, src); 1035 EmitXmmRegisterOperand(dst & 7, src);
1150 } 1036 }
1151 1037
1152
1153 void Assembler::movmskps(Register dst, XmmRegister src) { 1038 void Assembler::movmskps(Register dst, XmmRegister src) {
1154 ASSERT(src <= XMM15); 1039 ASSERT(src <= XMM15);
1155 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1040 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1156 EmitREX_RB(dst, src); 1041 EmitREX_RB(dst, src);
1157 EmitUint8(0x0F); 1042 EmitUint8(0x0F);
1158 EmitUint8(0x50); 1043 EmitUint8(0x50);
1159 EmitXmmRegisterOperand(dst & 7, src); 1044 EmitXmmRegisterOperand(dst & 7, src);
1160 } 1045 }
1161 1046
1162
1163 void Assembler::sqrtsd(XmmRegister dst, XmmRegister src) { 1047 void Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
1164 ASSERT(dst <= XMM15); 1048 ASSERT(dst <= XMM15);
1165 ASSERT(src <= XMM15); 1049 ASSERT(src <= XMM15);
1166 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1050 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1167 EmitUint8(0xF2); 1051 EmitUint8(0xF2);
1168 EmitREX_RB(dst, src); 1052 EmitREX_RB(dst, src);
1169 EmitUint8(0x0F); 1053 EmitUint8(0x0F);
1170 EmitUint8(0x51); 1054 EmitUint8(0x51);
1171 EmitXmmRegisterOperand(dst & 7, src); 1055 EmitXmmRegisterOperand(dst & 7, src);
1172 } 1056 }
1173 1057
1174
1175 void Assembler::xorpd(XmmRegister dst, const Address& src) { 1058 void Assembler::xorpd(XmmRegister dst, const Address& src) {
1176 ASSERT(dst <= XMM15); 1059 ASSERT(dst <= XMM15);
1177 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1060 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1178 EmitUint8(0x66); 1061 EmitUint8(0x66);
1179 EmitOperandREX(dst, src, REX_NONE); 1062 EmitOperandREX(dst, src, REX_NONE);
1180 EmitUint8(0x0F); 1063 EmitUint8(0x0F);
1181 EmitUint8(0x57); 1064 EmitUint8(0x57);
1182 EmitOperand(dst & 7, src); 1065 EmitOperand(dst & 7, src);
1183 } 1066 }
1184 1067
1185
1186 void Assembler::xorpd(XmmRegister dst, XmmRegister src) { 1068 void Assembler::xorpd(XmmRegister dst, XmmRegister src) {
1187 ASSERT(dst <= XMM15); 1069 ASSERT(dst <= XMM15);
1188 ASSERT(src <= XMM15); 1070 ASSERT(src <= XMM15);
1189 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1071 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1190 EmitUint8(0x66); 1072 EmitUint8(0x66);
1191 EmitREX_RB(dst, src); 1073 EmitREX_RB(dst, src);
1192 EmitUint8(0x0F); 1074 EmitUint8(0x0F);
1193 EmitUint8(0x57); 1075 EmitUint8(0x57);
1194 EmitXmmRegisterOperand(dst & 7, src); 1076 EmitXmmRegisterOperand(dst & 7, src);
1195 } 1077 }
1196 1078
1197
1198 void Assembler::xorps(XmmRegister dst, const Address& src) { 1079 void Assembler::xorps(XmmRegister dst, const Address& src) {
1199 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1080 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1200 EmitREX_RB(dst, src); 1081 EmitREX_RB(dst, src);
1201 EmitUint8(0x0F); 1082 EmitUint8(0x0F);
1202 EmitUint8(0x57); 1083 EmitUint8(0x57);
1203 EmitOperand(dst & 7, src); 1084 EmitOperand(dst & 7, src);
1204 } 1085 }
1205 1086
1206
1207 void Assembler::xorps(XmmRegister dst, XmmRegister src) { 1087 void Assembler::xorps(XmmRegister dst, XmmRegister src) {
1208 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1088 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1209 EmitREX_RB(dst, src); 1089 EmitREX_RB(dst, src);
1210 EmitUint8(0x0F); 1090 EmitUint8(0x0F);
1211 EmitUint8(0x57); 1091 EmitUint8(0x57);
1212 EmitXmmRegisterOperand(dst & 7, src); 1092 EmitXmmRegisterOperand(dst & 7, src);
1213 } 1093 }
1214 1094
1215 void Assembler::andpd(XmmRegister dst, const Address& src) { 1095 void Assembler::andpd(XmmRegister dst, const Address& src) {
1216 ASSERT(dst <= XMM15); 1096 ASSERT(dst <= XMM15);
1217 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1097 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1218 EmitUint8(0x66); 1098 EmitUint8(0x66);
1219 EmitOperandREX(dst, src, REX_NONE); 1099 EmitOperandREX(dst, src, REX_NONE);
1220 EmitUint8(0x0F); 1100 EmitUint8(0x0F);
1221 EmitUint8(0x54); 1101 EmitUint8(0x54);
1222 EmitOperand(dst & 7, src); 1102 EmitOperand(dst & 7, src);
1223 } 1103 }
1224 1104
1225
1226 void Assembler::cvtsi2sdq(XmmRegister dst, Register src) { 1105 void Assembler::cvtsi2sdq(XmmRegister dst, Register src) {
1227 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1106 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1228 ASSERT(dst <= XMM15); 1107 ASSERT(dst <= XMM15);
1229 Operand operand(src); 1108 Operand operand(src);
1230 EmitUint8(0xF2); 1109 EmitUint8(0xF2);
1231 EmitOperandREX(dst, operand, REX_W); 1110 EmitOperandREX(dst, operand, REX_W);
1232 EmitUint8(0x0F); 1111 EmitUint8(0x0F);
1233 EmitUint8(0x2A); 1112 EmitUint8(0x2A);
1234 EmitOperand(dst & 7, operand); 1113 EmitOperand(dst & 7, operand);
1235 } 1114 }
1236 1115
1237
1238 void Assembler::cvtsi2sdl(XmmRegister dst, Register src) { 1116 void Assembler::cvtsi2sdl(XmmRegister dst, Register src) {
1239 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1117 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1240 ASSERT(dst <= XMM15); 1118 ASSERT(dst <= XMM15);
1241 Operand operand(src); 1119 Operand operand(src);
1242 EmitUint8(0xF2); 1120 EmitUint8(0xF2);
1243 EmitOperandREX(dst, operand, REX_NONE); 1121 EmitOperandREX(dst, operand, REX_NONE);
1244 EmitUint8(0x0F); 1122 EmitUint8(0x0F);
1245 EmitUint8(0x2A); 1123 EmitUint8(0x2A);
1246 EmitOperand(dst & 7, operand); 1124 EmitOperand(dst & 7, operand);
1247 } 1125 }
1248 1126
1249
1250 void Assembler::cvttsd2siq(Register dst, XmmRegister src) { 1127 void Assembler::cvttsd2siq(Register dst, XmmRegister src) {
1251 ASSERT(src <= XMM15); 1128 ASSERT(src <= XMM15);
1252 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1129 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1253 EmitUint8(0xF2); 1130 EmitUint8(0xF2);
1254 Operand operand(dst); 1131 Operand operand(dst);
1255 EmitREX_RB(dst, src, REX_W); 1132 EmitREX_RB(dst, src, REX_W);
1256 EmitUint8(0x0F); 1133 EmitUint8(0x0F);
1257 EmitUint8(0x2C); 1134 EmitUint8(0x2C);
1258 EmitXmmRegisterOperand(dst & 7, src); 1135 EmitXmmRegisterOperand(dst & 7, src);
1259 } 1136 }
1260 1137
1261
1262 void Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) { 1138 void Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) {
1263 ASSERT(src <= XMM15); 1139 ASSERT(src <= XMM15);
1264 ASSERT(dst <= XMM15); 1140 ASSERT(dst <= XMM15);
1265 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1141 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1266 EmitUint8(0xF3); 1142 EmitUint8(0xF3);
1267 EmitREX_RB(dst, src); 1143 EmitREX_RB(dst, src);
1268 EmitUint8(0x0F); 1144 EmitUint8(0x0F);
1269 EmitUint8(0x5A); 1145 EmitUint8(0x5A);
1270 EmitXmmRegisterOperand(dst & 7, src); 1146 EmitXmmRegisterOperand(dst & 7, src);
1271 } 1147 }
1272 1148
1273
1274 void Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) { 1149 void Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) {
1275 ASSERT(src <= XMM15); 1150 ASSERT(src <= XMM15);
1276 ASSERT(dst <= XMM15); 1151 ASSERT(dst <= XMM15);
1277 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1152 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1278 EmitUint8(0xF2); 1153 EmitUint8(0xF2);
1279 EmitREX_RB(dst, src); 1154 EmitREX_RB(dst, src);
1280 EmitUint8(0x0F); 1155 EmitUint8(0x0F);
1281 EmitUint8(0x5A); 1156 EmitUint8(0x5A);
1282 EmitXmmRegisterOperand(dst & 7, src); 1157 EmitXmmRegisterOperand(dst & 7, src);
1283 } 1158 }
1284 1159
1285
1286 void Assembler::pxor(XmmRegister dst, XmmRegister src) { 1160 void Assembler::pxor(XmmRegister dst, XmmRegister src) {
1287 ASSERT(src <= XMM15); 1161 ASSERT(src <= XMM15);
1288 ASSERT(dst <= XMM15); 1162 ASSERT(dst <= XMM15);
1289 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1163 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1290 EmitUint8(0x66); 1164 EmitUint8(0x66);
1291 EmitREX_RB(dst, src); 1165 EmitREX_RB(dst, src);
1292 EmitUint8(0x0F); 1166 EmitUint8(0x0F);
1293 EmitUint8(0xEF); 1167 EmitUint8(0xEF);
1294 EmitXmmRegisterOperand(dst & 7, src); 1168 EmitXmmRegisterOperand(dst & 7, src);
1295 } 1169 }
1296 1170
1297
1298 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { 1171 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) {
1299 ASSERT(src <= XMM15); 1172 ASSERT(src <= XMM15);
1300 ASSERT(dst <= XMM15); 1173 ASSERT(dst <= XMM15);
1301 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1174 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1302 EmitUint8(0x66); 1175 EmitUint8(0x66);
1303 EmitREX_RB(dst, src); 1176 EmitREX_RB(dst, src);
1304 EmitUint8(0x0F); 1177 EmitUint8(0x0F);
1305 EmitUint8(0x3A); 1178 EmitUint8(0x3A);
1306 EmitUint8(0x0B); 1179 EmitUint8(0x0B);
1307 EmitXmmRegisterOperand(dst & 7, src); 1180 EmitXmmRegisterOperand(dst & 7, src);
1308 // Mask precision exeption. 1181 // Mask precision exeption.
1309 EmitUint8(static_cast<uint8_t>(mode) | 0x8); 1182 EmitUint8(static_cast<uint8_t>(mode) | 0x8);
1310 } 1183 }
1311 1184
1312
1313 void Assembler::fldl(const Address& src) { 1185 void Assembler::fldl(const Address& src) {
1314 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1186 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1315 EmitUint8(0xDD); 1187 EmitUint8(0xDD);
1316 EmitOperand(0, src); 1188 EmitOperand(0, src);
1317 } 1189 }
1318 1190
1319
1320 void Assembler::fstpl(const Address& dst) { 1191 void Assembler::fstpl(const Address& dst) {
1321 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1192 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1322 EmitUint8(0xDD); 1193 EmitUint8(0xDD);
1323 EmitOperand(3, dst); 1194 EmitOperand(3, dst);
1324 } 1195 }
1325 1196
1326
1327 void Assembler::fincstp() { 1197 void Assembler::fincstp() {
1328 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1198 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1329 EmitUint8(0xD9); 1199 EmitUint8(0xD9);
1330 EmitUint8(0xF7); 1200 EmitUint8(0xF7);
1331 } 1201 }
1332 1202
1333
1334 void Assembler::ffree(intptr_t value) { 1203 void Assembler::ffree(intptr_t value) {
1335 ASSERT(value < 7); 1204 ASSERT(value < 7);
1336 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1205 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1337 EmitUint8(0xDD); 1206 EmitUint8(0xDD);
1338 EmitUint8(0xC0 + value); 1207 EmitUint8(0xC0 + value);
1339 } 1208 }
1340 1209
1341
1342 void Assembler::fsin() { 1210 void Assembler::fsin() {
1343 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1211 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1344 EmitUint8(0xD9); 1212 EmitUint8(0xD9);
1345 EmitUint8(0xFE); 1213 EmitUint8(0xFE);
1346 } 1214 }
1347 1215
1348
1349 void Assembler::fcos() { 1216 void Assembler::fcos() {
1350 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1217 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1351 EmitUint8(0xD9); 1218 EmitUint8(0xD9);
1352 EmitUint8(0xFF); 1219 EmitUint8(0xFF);
1353 } 1220 }
1354 1221
1355
1356 void Assembler::xchgl(Register dst, Register src) { 1222 void Assembler::xchgl(Register dst, Register src) {
1357 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1223 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1358 Operand operand(src); 1224 Operand operand(src);
1359 EmitOperandREX(dst, operand, REX_NONE); 1225 EmitOperandREX(dst, operand, REX_NONE);
1360 EmitUint8(0x87); 1226 EmitUint8(0x87);
1361 EmitOperand(dst & 7, operand); 1227 EmitOperand(dst & 7, operand);
1362 } 1228 }
1363 1229
1364
1365 void Assembler::xchgq(Register dst, Register src) { 1230 void Assembler::xchgq(Register dst, Register src) {
1366 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1231 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1367 Operand operand(src); 1232 Operand operand(src);
1368 EmitOperandREX(dst, operand, REX_W); 1233 EmitOperandREX(dst, operand, REX_W);
1369 EmitUint8(0x87); 1234 EmitUint8(0x87);
1370 EmitOperand(dst & 7, operand); 1235 EmitOperand(dst & 7, operand);
1371 } 1236 }
1372 1237
1373
1374 void Assembler::cmpb(const Address& address, const Immediate& imm) { 1238 void Assembler::cmpb(const Address& address, const Immediate& imm) {
1375 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1239 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1376 EmitOperandREX(7, address, REX_NONE); 1240 EmitOperandREX(7, address, REX_NONE);
1377 EmitUint8(0x80); 1241 EmitUint8(0x80);
1378 EmitOperand(7, address); 1242 EmitOperand(7, address);
1379 ASSERT(imm.is_int8()); 1243 ASSERT(imm.is_int8());
1380 EmitUint8(imm.value() & 0xFF); 1244 EmitUint8(imm.value() & 0xFF);
1381 } 1245 }
1382 1246
1383
1384 void Assembler::cmpw(Register reg, const Address& address) { 1247 void Assembler::cmpw(Register reg, const Address& address) {
1385 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1248 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1386 EmitOperandSizeOverride(); 1249 EmitOperandSizeOverride();
1387 EmitOperandREX(reg, address, REX_NONE); 1250 EmitOperandREX(reg, address, REX_NONE);
1388 EmitUint8(0x3B); 1251 EmitUint8(0x3B);
1389 EmitOperand(reg & 7, address); 1252 EmitOperand(reg & 7, address);
1390 } 1253 }
1391 1254
1392
1393 void Assembler::cmpw(const Address& address, const Immediate& imm) { 1255 void Assembler::cmpw(const Address& address, const Immediate& imm) {
1394 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1256 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1395 EmitOperandSizeOverride(); 1257 EmitOperandSizeOverride();
1396 EmitOperandREX(7, address, REX_NONE); 1258 EmitOperandREX(7, address, REX_NONE);
1397 EmitUint8(0x81); 1259 EmitUint8(0x81);
1398 EmitOperand(7, address); 1260 EmitOperand(7, address);
1399 EmitUint8(imm.value() & 0xFF); 1261 EmitUint8(imm.value() & 0xFF);
1400 EmitUint8((imm.value() >> 8) & 0xFF); 1262 EmitUint8((imm.value() >> 8) & 0xFF);
1401 } 1263 }
1402 1264
1403
1404 void Assembler::cmpl(Register reg, const Immediate& imm) { 1265 void Assembler::cmpl(Register reg, const Immediate& imm) {
1405 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1266 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1406 EmitRegisterREX(reg, REX_NONE); 1267 EmitRegisterREX(reg, REX_NONE);
1407 EmitComplex(7, Operand(reg), imm); 1268 EmitComplex(7, Operand(reg), imm);
1408 } 1269 }
1409 1270
1410
1411 void Assembler::cmpl(Register reg0, Register reg1) { 1271 void Assembler::cmpl(Register reg0, Register reg1) {
1412 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1272 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1413 Operand operand(reg1); 1273 Operand operand(reg1);
1414 EmitOperandREX(reg0, operand, REX_NONE); 1274 EmitOperandREX(reg0, operand, REX_NONE);
1415 EmitUint8(0x3B); 1275 EmitUint8(0x3B);
1416 EmitOperand(reg0 & 7, operand); 1276 EmitOperand(reg0 & 7, operand);
1417 } 1277 }
1418 1278
1419
1420 void Assembler::cmpl(Register reg, const Address& address) { 1279 void Assembler::cmpl(Register reg, const Address& address) {
1421 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1280 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1422 EmitOperandREX(reg, address, REX_NONE); 1281 EmitOperandREX(reg, address, REX_NONE);
1423 EmitUint8(0x3B); 1282 EmitUint8(0x3B);
1424 EmitOperand(reg & 7, address); 1283 EmitOperand(reg & 7, address);
1425 } 1284 }
1426 1285
1427
1428 void Assembler::cmpl(const Address& address, const Immediate& imm) { 1286 void Assembler::cmpl(const Address& address, const Immediate& imm) {
1429 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1287 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1430 Operand operand(address); 1288 Operand operand(address);
1431 EmitOperandREX(7, operand, REX_NONE); 1289 EmitOperandREX(7, operand, REX_NONE);
1432 EmitComplex(7, operand, imm); 1290 EmitComplex(7, operand, imm);
1433 } 1291 }
1434 1292
1435
1436 void Assembler::cmpq(const Address& address, Register reg) { 1293 void Assembler::cmpq(const Address& address, Register reg) {
1437 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1294 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1438 EmitOperandREX(reg, address, REX_W); 1295 EmitOperandREX(reg, address, REX_W);
1439 EmitUint8(0x39); 1296 EmitUint8(0x39);
1440 EmitOperand(reg & 7, address); 1297 EmitOperand(reg & 7, address);
1441 } 1298 }
1442 1299
1443
1444 void Assembler::cmpq(const Address& address, const Immediate& imm) { 1300 void Assembler::cmpq(const Address& address, const Immediate& imm) {
1445 if (imm.is_int32()) { 1301 if (imm.is_int32()) {
1446 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1302 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1447 Operand operand(address); 1303 Operand operand(address);
1448 EmitOperandREX(7, operand, REX_W); 1304 EmitOperandREX(7, operand, REX_W);
1449 EmitComplex(7, operand, imm); 1305 EmitComplex(7, operand, imm);
1450 } else { 1306 } else {
1451 movq(TMP, imm); 1307 movq(TMP, imm);
1452 cmpq(address, TMP); 1308 cmpq(address, TMP);
1453 } 1309 }
1454 } 1310 }
1455 1311
1456
1457 void Assembler::cmpq(Register reg, const Immediate& imm) { 1312 void Assembler::cmpq(Register reg, const Immediate& imm) {
1458 if (imm.is_int32()) { 1313 if (imm.is_int32()) {
1459 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1314 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1460 EmitRegisterREX(reg, REX_W); 1315 EmitRegisterREX(reg, REX_W);
1461 EmitComplex(7, Operand(reg), imm); 1316 EmitComplex(7, Operand(reg), imm);
1462 } else { 1317 } else {
1463 ASSERT(reg != TMP); 1318 ASSERT(reg != TMP);
1464 movq(TMP, imm); 1319 movq(TMP, imm);
1465 cmpq(reg, TMP); 1320 cmpq(reg, TMP);
1466 } 1321 }
1467 } 1322 }
1468 1323
1469
1470 void Assembler::cmpq(Register reg0, Register reg1) { 1324 void Assembler::cmpq(Register reg0, Register reg1) {
1471 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1325 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1472 Operand operand(reg1); 1326 Operand operand(reg1);
1473 EmitOperandREX(reg0, operand, REX_W); 1327 EmitOperandREX(reg0, operand, REX_W);
1474 EmitUint8(0x3B); 1328 EmitUint8(0x3B);
1475 EmitOperand(reg0 & 7, operand); 1329 EmitOperand(reg0 & 7, operand);
1476 } 1330 }
1477 1331
1478
1479 void Assembler::cmpq(Register reg, const Address& address) { 1332 void Assembler::cmpq(Register reg, const Address& address) {
1480 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1333 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1481 EmitOperandREX(reg, address, REX_W); 1334 EmitOperandREX(reg, address, REX_W);
1482 EmitUint8(0x3B); 1335 EmitUint8(0x3B);
1483 EmitOperand(reg & 7, address); 1336 EmitOperand(reg & 7, address);
1484 } 1337 }
1485 1338
1486
1487 void Assembler::CompareImmediate(Register reg, const Immediate& imm) { 1339 void Assembler::CompareImmediate(Register reg, const Immediate& imm) {
1488 if (imm.is_int32()) { 1340 if (imm.is_int32()) {
1489 cmpq(reg, imm); 1341 cmpq(reg, imm);
1490 } else { 1342 } else {
1491 ASSERT(reg != TMP); 1343 ASSERT(reg != TMP);
1492 LoadImmediate(TMP, imm); 1344 LoadImmediate(TMP, imm);
1493 cmpq(reg, TMP); 1345 cmpq(reg, TMP);
1494 } 1346 }
1495 } 1347 }
1496 1348
1497
1498 void Assembler::CompareImmediate(const Address& address, const Immediate& imm) { 1349 void Assembler::CompareImmediate(const Address& address, const Immediate& imm) {
1499 if (imm.is_int32()) { 1350 if (imm.is_int32()) {
1500 cmpq(address, imm); 1351 cmpq(address, imm);
1501 } else { 1352 } else {
1502 LoadImmediate(TMP, imm); 1353 LoadImmediate(TMP, imm);
1503 cmpq(address, TMP); 1354 cmpq(address, TMP);
1504 } 1355 }
1505 } 1356 }
1506 1357
1507
1508 void Assembler::testl(Register reg1, Register reg2) { 1358 void Assembler::testl(Register reg1, Register reg2) {
1509 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1359 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1510 Operand operand(reg2); 1360 Operand operand(reg2);
1511 EmitOperandREX(reg1, operand, REX_NONE); 1361 EmitOperandREX(reg1, operand, REX_NONE);
1512 EmitUint8(0x85); 1362 EmitUint8(0x85);
1513 EmitOperand(reg1 & 7, operand); 1363 EmitOperand(reg1 & 7, operand);
1514 } 1364 }
1515 1365
1516
1517 void Assembler::testl(Register reg, const Immediate& imm) { 1366 void Assembler::testl(Register reg, const Immediate& imm) {
1518 // TODO(kasperl): Deal with registers r8-r15 using the short 1367 // TODO(kasperl): Deal with registers r8-r15 using the short
1519 // encoding form of the immediate? 1368 // encoding form of the immediate?
1520 1369
1521 // We are using RBP for the exception marker. See testl(Label*). 1370 // We are using RBP for the exception marker. See testl(Label*).
1522 ASSERT(reg != RBP); 1371 ASSERT(reg != RBP);
1523 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1372 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1524 // For registers that have a byte variant (RAX, RBX, RCX, and RDX) 1373 // For registers that have a byte variant (RAX, RBX, RCX, and RDX)
1525 // we only test the byte register to keep the encoding short. 1374 // we only test the byte register to keep the encoding short.
1526 if (imm.is_uint8() && reg < 4) { 1375 if (imm.is_uint8() && reg < 4) {
(...skipping 11 matching lines...) Expand all
1538 EmitUint8(0xA9); 1387 EmitUint8(0xA9);
1539 } else { 1388 } else {
1540 EmitRegisterREX(reg, REX_NONE); 1389 EmitRegisterREX(reg, REX_NONE);
1541 EmitUint8(0xF7); 1390 EmitUint8(0xF7);
1542 EmitUint8(0xC0 | (reg & 7)); 1391 EmitUint8(0xC0 | (reg & 7));
1543 } 1392 }
1544 EmitImmediate(imm); 1393 EmitImmediate(imm);
1545 } 1394 }
1546 } 1395 }
1547 1396
1548
1549 void Assembler::testb(const Address& address, const Immediate& imm) { 1397 void Assembler::testb(const Address& address, const Immediate& imm) {
1550 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1398 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1551 EmitOperandREX(0, address, REX_NONE); 1399 EmitOperandREX(0, address, REX_NONE);
1552 EmitUint8(0xF6); 1400 EmitUint8(0xF6);
1553 EmitOperand(0, address); 1401 EmitOperand(0, address);
1554 ASSERT(imm.is_int8()); 1402 ASSERT(imm.is_int8());
1555 EmitUint8(imm.value() & 0xFF); 1403 EmitUint8(imm.value() & 0xFF);
1556 } 1404 }
1557 1405
1558
1559 void Assembler::testq(Register reg1, Register reg2) { 1406 void Assembler::testq(Register reg1, Register reg2) {
1560 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1407 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1561 Operand operand(reg2); 1408 Operand operand(reg2);
1562 EmitOperandREX(reg1, operand, REX_W); 1409 EmitOperandREX(reg1, operand, REX_W);
1563 EmitUint8(0x85); 1410 EmitUint8(0x85);
1564 EmitOperand(reg1 & 7, operand); 1411 EmitOperand(reg1 & 7, operand);
1565 } 1412 }
1566 1413
1567
1568 void Assembler::testq(Register reg, const Immediate& imm) { 1414 void Assembler::testq(Register reg, const Immediate& imm) {
1569 // TODO(kasperl): Deal with registers r8-r15 using the short 1415 // TODO(kasperl): Deal with registers r8-r15 using the short
1570 // encoding form of the immediate? 1416 // encoding form of the immediate?
1571 1417
1572 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1418 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1573 // For registers that have a byte variant (RAX, RBX, RCX, and RDX) 1419 // For registers that have a byte variant (RAX, RBX, RCX, and RDX)
1574 // we only test the byte register to keep the encoding short. 1420 // we only test the byte register to keep the encoding short.
1575 if (imm.is_uint8() && reg < 4) { 1421 if (imm.is_uint8() && reg < 4) {
1576 // Use zero-extended 8-bit immediate. 1422 // Use zero-extended 8-bit immediate.
1577 if (reg == RAX) { 1423 if (reg == RAX) {
1578 EmitUint8(0xA8); 1424 EmitUint8(0xA8);
1579 } else { 1425 } else {
1580 EmitUint8(0xF6); 1426 EmitUint8(0xF6);
1581 EmitUint8(0xC0 + reg); 1427 EmitUint8(0xC0 + reg);
1582 } 1428 }
1583 EmitUint8(imm.value() & 0xFF); 1429 EmitUint8(imm.value() & 0xFF);
1584 } else { 1430 } else {
1585 ASSERT(imm.is_int32()); 1431 ASSERT(imm.is_int32());
1586 if (reg == RAX) { 1432 if (reg == RAX) {
1587 EmitUint8(0xA9 | REX_W); 1433 EmitUint8(0xA9 | REX_W);
1588 } else { 1434 } else {
1589 EmitRegisterREX(reg, REX_W); 1435 EmitRegisterREX(reg, REX_W);
1590 EmitUint8(0xF7); 1436 EmitUint8(0xF7);
1591 EmitUint8(0xC0 | (reg & 7)); 1437 EmitUint8(0xC0 | (reg & 7));
1592 } 1438 }
1593 EmitImmediate(imm); 1439 EmitImmediate(imm);
1594 } 1440 }
1595 } 1441 }
1596 1442
1597
1598 void Assembler::TestImmediate(Register dst, const Immediate& imm) { 1443 void Assembler::TestImmediate(Register dst, const Immediate& imm) {
1599 if (imm.is_int32()) { 1444 if (imm.is_int32()) {
1600 testq(dst, imm); 1445 testq(dst, imm);
1601 } else { 1446 } else {
1602 ASSERT(dst != TMP); 1447 ASSERT(dst != TMP);
1603 LoadImmediate(TMP, imm); 1448 LoadImmediate(TMP, imm);
1604 testq(dst, TMP); 1449 testq(dst, TMP);
1605 } 1450 }
1606 } 1451 }
1607 1452
1608
1609 void Assembler::andl(Register dst, Register src) { 1453 void Assembler::andl(Register dst, Register src) {
1610 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1454 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1611 Operand operand(src); 1455 Operand operand(src);
1612 EmitOperandREX(dst, operand, REX_NONE); 1456 EmitOperandREX(dst, operand, REX_NONE);
1613 EmitUint8(0x23); 1457 EmitUint8(0x23);
1614 EmitOperand(dst & 7, operand); 1458 EmitOperand(dst & 7, operand);
1615 } 1459 }
1616 1460
1617
1618 void Assembler::andl(Register dst, const Immediate& imm) { 1461 void Assembler::andl(Register dst, const Immediate& imm) {
1619 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1462 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1620 EmitRegisterREX(dst, REX_NONE); 1463 EmitRegisterREX(dst, REX_NONE);
1621 EmitComplex(4, Operand(dst), imm); 1464 EmitComplex(4, Operand(dst), imm);
1622 } 1465 }
1623 1466
1624
1625 void Assembler::orl(Register dst, Register src) { 1467 void Assembler::orl(Register dst, Register src) {
1626 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1468 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1627 Operand operand(src); 1469 Operand operand(src);
1628 EmitOperandREX(dst, operand, REX_NONE); 1470 EmitOperandREX(dst, operand, REX_NONE);
1629 EmitUint8(0x0B); 1471 EmitUint8(0x0B);
1630 EmitOperand(dst & 7, operand); 1472 EmitOperand(dst & 7, operand);
1631 } 1473 }
1632 1474
1633
1634 void Assembler::orl(Register dst, const Immediate& imm) { 1475 void Assembler::orl(Register dst, const Immediate& imm) {
1635 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1476 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1636 EmitRegisterREX(dst, REX_NONE); 1477 EmitRegisterREX(dst, REX_NONE);
1637 EmitComplex(1, Operand(dst), imm); 1478 EmitComplex(1, Operand(dst), imm);
1638 } 1479 }
1639 1480
1640
1641 void Assembler::orl(const Address& address, Register reg) { 1481 void Assembler::orl(const Address& address, Register reg) {
1642 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1482 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1643 EmitOperandREX(reg, address, REX_NONE); 1483 EmitOperandREX(reg, address, REX_NONE);
1644 EmitUint8(0x09); 1484 EmitUint8(0x09);
1645 EmitOperand(reg & 7, address); 1485 EmitOperand(reg & 7, address);
1646 } 1486 }
1647 1487
1648
1649 void Assembler::xorl(Register dst, Register src) { 1488 void Assembler::xorl(Register dst, Register src) {
1650 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1489 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1651 Operand operand(src); 1490 Operand operand(src);
1652 EmitOperandREX(dst, operand, REX_NONE); 1491 EmitOperandREX(dst, operand, REX_NONE);
1653 EmitUint8(0x33); 1492 EmitUint8(0x33);
1654 EmitOperand(dst & 7, operand); 1493 EmitOperand(dst & 7, operand);
1655 } 1494 }
1656 1495
1657
1658 void Assembler::andq(Register dst, Register src) { 1496 void Assembler::andq(Register dst, Register src) {
1659 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1497 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1660 Operand operand(src); 1498 Operand operand(src);
1661 EmitOperandREX(dst, operand, REX_W); 1499 EmitOperandREX(dst, operand, REX_W);
1662 EmitUint8(0x23); 1500 EmitUint8(0x23);
1663 EmitOperand(dst & 7, operand); 1501 EmitOperand(dst & 7, operand);
1664 } 1502 }
1665 1503
1666
1667 void Assembler::andq(Register dst, const Address& address) { 1504 void Assembler::andq(Register dst, const Address& address) {
1668 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1505 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1669 EmitOperandREX(dst, address, REX_W); 1506 EmitOperandREX(dst, address, REX_W);
1670 EmitUint8(0x23); 1507 EmitUint8(0x23);
1671 EmitOperand(dst & 7, address); 1508 EmitOperand(dst & 7, address);
1672 } 1509 }
1673 1510
1674
1675 void Assembler::andq(Register dst, const Immediate& imm) { 1511 void Assembler::andq(Register dst, const Immediate& imm) {
1676 if (imm.is_int32()) { 1512 if (imm.is_int32()) {
1677 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1513 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1678 EmitRegisterREX(dst, REX_W); 1514 EmitRegisterREX(dst, REX_W);
1679 EmitComplex(4, Operand(dst), imm); 1515 EmitComplex(4, Operand(dst), imm);
1680 } else { 1516 } else {
1681 ASSERT(dst != TMP); 1517 ASSERT(dst != TMP);
1682 movq(TMP, imm); 1518 movq(TMP, imm);
1683 andq(dst, TMP); 1519 andq(dst, TMP);
1684 } 1520 }
1685 } 1521 }
1686 1522
1687
1688 void Assembler::AndImmediate(Register dst, const Immediate& imm) { 1523 void Assembler::AndImmediate(Register dst, const Immediate& imm) {
1689 if (imm.is_int32()) { 1524 if (imm.is_int32()) {
1690 andq(dst, imm); 1525 andq(dst, imm);
1691 } else { 1526 } else {
1692 ASSERT(dst != TMP); 1527 ASSERT(dst != TMP);
1693 LoadImmediate(TMP, imm); 1528 LoadImmediate(TMP, imm);
1694 andq(dst, TMP); 1529 andq(dst, TMP);
1695 } 1530 }
1696 } 1531 }
1697 1532
1698
1699 void Assembler::orq(Register dst, Register src) { 1533 void Assembler::orq(Register dst, Register src) {
1700 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1534 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1701 Operand operand(src); 1535 Operand operand(src);
1702 EmitOperandREX(dst, operand, REX_W); 1536 EmitOperandREX(dst, operand, REX_W);
1703 EmitUint8(0x0B); 1537 EmitUint8(0x0B);
1704 EmitOperand(dst & 7, operand); 1538 EmitOperand(dst & 7, operand);
1705 } 1539 }
1706 1540
1707
1708 void Assembler::orq(Register dst, const Address& address) { 1541 void Assembler::orq(Register dst, const Address& address) {
1709 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1542 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1710 EmitOperandREX(dst, address, REX_W); 1543 EmitOperandREX(dst, address, REX_W);
1711 EmitUint8(0x0B); 1544 EmitUint8(0x0B);
1712 EmitOperand(dst & 7, address); 1545 EmitOperand(dst & 7, address);
1713 } 1546 }
1714 1547
1715
1716 void Assembler::orq(Register dst, const Immediate& imm) { 1548 void Assembler::orq(Register dst, const Immediate& imm) {
1717 if (imm.is_int32()) { 1549 if (imm.is_int32()) {
1718 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1550 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1719 EmitRegisterREX(dst, REX_W); 1551 EmitRegisterREX(dst, REX_W);
1720 EmitComplex(1, Operand(dst), imm); 1552 EmitComplex(1, Operand(dst), imm);
1721 } else { 1553 } else {
1722 ASSERT(dst != TMP); 1554 ASSERT(dst != TMP);
1723 movq(TMP, imm); 1555 movq(TMP, imm);
1724 orq(dst, TMP); 1556 orq(dst, TMP);
1725 } 1557 }
1726 } 1558 }
1727 1559
1728
1729 void Assembler::OrImmediate(Register dst, const Immediate& imm) { 1560 void Assembler::OrImmediate(Register dst, const Immediate& imm) {
1730 if (imm.is_int32()) { 1561 if (imm.is_int32()) {
1731 orq(dst, imm); 1562 orq(dst, imm);
1732 } else { 1563 } else {
1733 ASSERT(dst != TMP); 1564 ASSERT(dst != TMP);
1734 LoadImmediate(TMP, imm); 1565 LoadImmediate(TMP, imm);
1735 orq(dst, TMP); 1566 orq(dst, TMP);
1736 } 1567 }
1737 } 1568 }
1738 1569
1739
1740 void Assembler::xorq(Register dst, Register src) { 1570 void Assembler::xorq(Register dst, Register src) {
1741 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1571 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1742 Operand operand(src); 1572 Operand operand(src);
1743 EmitOperandREX(dst, operand, REX_W); 1573 EmitOperandREX(dst, operand, REX_W);
1744 EmitUint8(0x33); 1574 EmitUint8(0x33);
1745 EmitOperand(dst & 7, operand); 1575 EmitOperand(dst & 7, operand);
1746 } 1576 }
1747 1577
1748
1749 void Assembler::xorq(Register dst, const Address& address) { 1578 void Assembler::xorq(Register dst, const Address& address) {
1750 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1579 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1751 EmitOperandREX(dst, address, REX_W); 1580 EmitOperandREX(dst, address, REX_W);
1752 EmitUint8(0x33); 1581 EmitUint8(0x33);
1753 EmitOperand(dst & 7, address); 1582 EmitOperand(dst & 7, address);
1754 } 1583 }
1755 1584
1756
1757 void Assembler::xorq(const Address& dst, Register src) { 1585 void Assembler::xorq(const Address& dst, Register src) {
1758 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1586 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1759 EmitOperandREX(src, dst, REX_W); 1587 EmitOperandREX(src, dst, REX_W);
1760 EmitUint8(0x31); 1588 EmitUint8(0x31);
1761 EmitOperand(src & 7, dst); 1589 EmitOperand(src & 7, dst);
1762 } 1590 }
1763 1591
1764
1765 void Assembler::xorq(Register dst, const Immediate& imm) { 1592 void Assembler::xorq(Register dst, const Immediate& imm) {
1766 if (imm.is_int32()) { 1593 if (imm.is_int32()) {
1767 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1594 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1768 EmitRegisterREX(dst, REX_W); 1595 EmitRegisterREX(dst, REX_W);
1769 EmitComplex(6, Operand(dst), imm); 1596 EmitComplex(6, Operand(dst), imm);
1770 } else { 1597 } else {
1771 ASSERT(dst != TMP); 1598 ASSERT(dst != TMP);
1772 movq(TMP, imm); 1599 movq(TMP, imm);
1773 xorq(dst, TMP); 1600 xorq(dst, TMP);
1774 } 1601 }
1775 } 1602 }
1776 1603
1777
1778 void Assembler::XorImmediate(Register dst, const Immediate& imm) { 1604 void Assembler::XorImmediate(Register dst, const Immediate& imm) {
1779 if (imm.is_int32()) { 1605 if (imm.is_int32()) {
1780 xorq(dst, imm); 1606 xorq(dst, imm);
1781 } else { 1607 } else {
1782 ASSERT(dst != TMP); 1608 ASSERT(dst != TMP);
1783 LoadImmediate(TMP, imm); 1609 LoadImmediate(TMP, imm);
1784 xorq(dst, TMP); 1610 xorq(dst, TMP);
1785 } 1611 }
1786 } 1612 }
1787 1613
1788
1789 void Assembler::addl(Register dst, Register src) { 1614 void Assembler::addl(Register dst, Register src) {
1790 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1615 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1791 Operand operand(src); 1616 Operand operand(src);
1792 EmitOperandREX(dst, operand, REX_NONE); 1617 EmitOperandREX(dst, operand, REX_NONE);
1793 EmitUint8(0x03); 1618 EmitUint8(0x03);
1794 EmitOperand(dst & 7, operand); 1619 EmitOperand(dst & 7, operand);
1795 } 1620 }
1796 1621
1797
1798 void Assembler::addl(Register dst, const Immediate& imm) { 1622 void Assembler::addl(Register dst, const Immediate& imm) {
1799 ASSERT(imm.is_int32()); 1623 ASSERT(imm.is_int32());
1800 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1624 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1801 EmitRegisterREX(dst, REX_NONE); 1625 EmitRegisterREX(dst, REX_NONE);
1802 EmitComplex(0, Operand(dst), imm); 1626 EmitComplex(0, Operand(dst), imm);
1803 } 1627 }
1804 1628
1805
1806 void Assembler::addl(Register dst, const Address& address) { 1629 void Assembler::addl(Register dst, const Address& address) {
1807 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1630 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1808 EmitOperandREX(dst, address, REX_NONE); 1631 EmitOperandREX(dst, address, REX_NONE);
1809 EmitUint8(0x03); 1632 EmitUint8(0x03);
1810 EmitOperand(dst & 7, address); 1633 EmitOperand(dst & 7, address);
1811 } 1634 }
1812 1635
1813
1814 void Assembler::addl(const Address& address, Register src) { 1636 void Assembler::addl(const Address& address, Register src) {
1815 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1637 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1816 EmitOperandREX(src, address, REX_NONE); 1638 EmitOperandREX(src, address, REX_NONE);
1817 EmitUint8(0x01); 1639 EmitUint8(0x01);
1818 EmitOperand(src & 7, address); 1640 EmitOperand(src & 7, address);
1819 } 1641 }
1820 1642
1821
1822 void Assembler::adcl(Register dst, Register src) { 1643 void Assembler::adcl(Register dst, Register src) {
1823 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1644 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1824 Operand operand(src); 1645 Operand operand(src);
1825 EmitOperandREX(dst, operand, REX_NONE); 1646 EmitOperandREX(dst, operand, REX_NONE);
1826 EmitUint8(0x13); 1647 EmitUint8(0x13);
1827 EmitOperand(dst & 7, operand); 1648 EmitOperand(dst & 7, operand);
1828 } 1649 }
1829 1650
1830
1831 void Assembler::adcl(Register dst, const Immediate& imm) { 1651 void Assembler::adcl(Register dst, const Immediate& imm) {
1832 ASSERT(imm.is_int32()); 1652 ASSERT(imm.is_int32());
1833 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1653 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1834 EmitRegisterREX(dst, REX_NONE); 1654 EmitRegisterREX(dst, REX_NONE);
1835 EmitComplex(2, Operand(dst), imm); 1655 EmitComplex(2, Operand(dst), imm);
1836 } 1656 }
1837 1657
1838
1839 void Assembler::adcl(Register dst, const Address& address) { 1658 void Assembler::adcl(Register dst, const Address& address) {
1840 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1659 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1841 EmitOperandREX(dst, address, REX_NONE); 1660 EmitOperandREX(dst, address, REX_NONE);
1842 EmitUint8(0x13); 1661 EmitUint8(0x13);
1843 EmitOperand(dst & 7, address); 1662 EmitOperand(dst & 7, address);
1844 } 1663 }
1845 1664
1846
1847 void Assembler::addq(Register dst, Register src) { 1665 void Assembler::addq(Register dst, Register src) {
1848 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1666 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1849 Operand operand(src); 1667 Operand operand(src);
1850 EmitOperandREX(dst, operand, REX_W); 1668 EmitOperandREX(dst, operand, REX_W);
1851 EmitUint8(0x03); 1669 EmitUint8(0x03);
1852 EmitOperand(dst & 7, operand); 1670 EmitOperand(dst & 7, operand);
1853 } 1671 }
1854 1672
1855
1856 void Assembler::addq(Register dst, const Address& address) { 1673 void Assembler::addq(Register dst, const Address& address) {
1857 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1674 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1858 EmitOperandREX(dst, address, REX_W); 1675 EmitOperandREX(dst, address, REX_W);
1859 EmitUint8(0x03); 1676 EmitUint8(0x03);
1860 EmitOperand(dst & 7, address); 1677 EmitOperand(dst & 7, address);
1861 } 1678 }
1862 1679
1863
1864 void Assembler::addq(Register dst, const Immediate& imm) { 1680 void Assembler::addq(Register dst, const Immediate& imm) {
1865 if (imm.is_int32()) { 1681 if (imm.is_int32()) {
1866 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1682 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1867 EmitRegisterREX(dst, REX_W); 1683 EmitRegisterREX(dst, REX_W);
1868 EmitComplex(0, Operand(dst), imm); 1684 EmitComplex(0, Operand(dst), imm);
1869 } else { 1685 } else {
1870 ASSERT(dst != TMP); 1686 ASSERT(dst != TMP);
1871 movq(TMP, imm); 1687 movq(TMP, imm);
1872 addq(dst, TMP); 1688 addq(dst, TMP);
1873 } 1689 }
1874 } 1690 }
1875 1691
1876
1877 void Assembler::addq(const Address& address, const Immediate& imm) { 1692 void Assembler::addq(const Address& address, const Immediate& imm) {
1878 if (imm.is_int32()) { 1693 if (imm.is_int32()) {
1879 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1694 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1880 EmitOperandREX(0, address, REX_W); 1695 EmitOperandREX(0, address, REX_W);
1881 EmitComplex(0, Operand(address), imm); 1696 EmitComplex(0, Operand(address), imm);
1882 } else { 1697 } else {
1883 movq(TMP, imm); 1698 movq(TMP, imm);
1884 addq(address, TMP); 1699 addq(address, TMP);
1885 } 1700 }
1886 } 1701 }
1887 1702
1888
1889 void Assembler::addq(const Address& address, Register src) { 1703 void Assembler::addq(const Address& address, Register src) {
1890 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1704 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1891 EmitOperandREX(src, address, REX_W); 1705 EmitOperandREX(src, address, REX_W);
1892 EmitUint8(0x01); 1706 EmitUint8(0x01);
1893 EmitOperand(src & 7, address); 1707 EmitOperand(src & 7, address);
1894 } 1708 }
1895 1709
1896
1897 void Assembler::adcq(Register dst, Register src) { 1710 void Assembler::adcq(Register dst, Register src) {
1898 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1711 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1899 Operand operand(src); 1712 Operand operand(src);
1900 EmitOperandREX(dst, operand, REX_W); 1713 EmitOperandREX(dst, operand, REX_W);
1901 EmitUint8(0x13); 1714 EmitUint8(0x13);
1902 EmitOperand(dst & 7, operand); 1715 EmitOperand(dst & 7, operand);
1903 } 1716 }
1904 1717
1905
1906 void Assembler::adcq(Register dst, const Immediate& imm) { 1718 void Assembler::adcq(Register dst, const Immediate& imm) {
1907 if (imm.is_int32()) { 1719 if (imm.is_int32()) {
1908 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1720 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1909 EmitRegisterREX(dst, REX_W); 1721 EmitRegisterREX(dst, REX_W);
1910 EmitComplex(2, Operand(dst), imm); 1722 EmitComplex(2, Operand(dst), imm);
1911 } else { 1723 } else {
1912 ASSERT(dst != TMP); 1724 ASSERT(dst != TMP);
1913 movq(TMP, imm); 1725 movq(TMP, imm);
1914 adcq(dst, TMP); 1726 adcq(dst, TMP);
1915 } 1727 }
1916 } 1728 }
1917 1729
1918
1919 void Assembler::adcq(Register dst, const Address& address) { 1730 void Assembler::adcq(Register dst, const Address& address) {
1920 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1731 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1921 EmitOperandREX(dst, address, REX_W); 1732 EmitOperandREX(dst, address, REX_W);
1922 EmitUint8(0x13); 1733 EmitUint8(0x13);
1923 EmitOperand(dst & 7, address); 1734 EmitOperand(dst & 7, address);
1924 } 1735 }
1925 1736
1926
1927 void Assembler::subl(Register dst, Register src) { 1737 void Assembler::subl(Register dst, Register src) {
1928 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1738 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1929 Operand operand(src); 1739 Operand operand(src);
1930 EmitOperandREX(dst, operand, REX_NONE); 1740 EmitOperandREX(dst, operand, REX_NONE);
1931 EmitUint8(0x2B); 1741 EmitUint8(0x2B);
1932 EmitOperand(dst & 7, operand); 1742 EmitOperand(dst & 7, operand);
1933 } 1743 }
1934 1744
1935
1936 void Assembler::subl(Register dst, const Immediate& imm) { 1745 void Assembler::subl(Register dst, const Immediate& imm) {
1937 ASSERT(imm.is_int32()); 1746 ASSERT(imm.is_int32());
1938 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1747 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1939 EmitRegisterREX(dst, REX_NONE); 1748 EmitRegisterREX(dst, REX_NONE);
1940 EmitComplex(3, Operand(dst), imm); 1749 EmitComplex(3, Operand(dst), imm);
1941 } 1750 }
1942 1751
1943
1944 void Assembler::subl(Register dst, const Address& address) { 1752 void Assembler::subl(Register dst, const Address& address) {
1945 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1753 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1946 EmitOperandREX(dst, address, REX_NONE); 1754 EmitOperandREX(dst, address, REX_NONE);
1947 EmitUint8(0x2B); 1755 EmitUint8(0x2B);
1948 EmitOperand(dst & 7, address); 1756 EmitOperand(dst & 7, address);
1949 } 1757 }
1950 1758
1951
1952 void Assembler::sbbl(Register dst, Register src) { 1759 void Assembler::sbbl(Register dst, Register src) {
1953 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1760 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1954 Operand operand(src); 1761 Operand operand(src);
1955 EmitOperandREX(dst, operand, REX_NONE); 1762 EmitOperandREX(dst, operand, REX_NONE);
1956 EmitUint8(0x1B); 1763 EmitUint8(0x1B);
1957 EmitOperand(dst & 7, operand); 1764 EmitOperand(dst & 7, operand);
1958 } 1765 }
1959 1766
1960
1961 void Assembler::sbbl(Register dst, const Immediate& imm) { 1767 void Assembler::sbbl(Register dst, const Immediate& imm) {
1962 ASSERT(imm.is_int32()); 1768 ASSERT(imm.is_int32());
1963 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1769 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1964 EmitRegisterREX(dst, REX_NONE); 1770 EmitRegisterREX(dst, REX_NONE);
1965 EmitComplex(3, Operand(dst), imm); 1771 EmitComplex(3, Operand(dst), imm);
1966 } 1772 }
1967 1773
1968
1969 void Assembler::sbbl(Register dst, const Address& address) { 1774 void Assembler::sbbl(Register dst, const Address& address) {
1970 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1775 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1971 EmitOperandREX(dst, address, REX_NONE); 1776 EmitOperandREX(dst, address, REX_NONE);
1972 EmitUint8(0x1B); 1777 EmitUint8(0x1B);
1973 EmitOperand(dst & 7, address); 1778 EmitOperand(dst & 7, address);
1974 } 1779 }
1975 1780
1976
1977 void Assembler::cdq() { 1781 void Assembler::cdq() {
1978 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1782 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1979 EmitUint8(0x99); 1783 EmitUint8(0x99);
1980 } 1784 }
1981 1785
1982
1983 void Assembler::cqo() { 1786 void Assembler::cqo() {
1984 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1787 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1985 EmitRegisterREX(RAX, REX_W); 1788 EmitRegisterREX(RAX, REX_W);
1986 EmitUint8(0x99); 1789 EmitUint8(0x99);
1987 } 1790 }
1988 1791
1989
1990 void Assembler::idivl(Register reg) { 1792 void Assembler::idivl(Register reg) {
1991 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1793 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1992 EmitRegisterREX(reg, REX_NONE); 1794 EmitRegisterREX(reg, REX_NONE);
1993 EmitUint8(0xF7); 1795 EmitUint8(0xF7);
1994 EmitOperand(7, Operand(reg)); 1796 EmitOperand(7, Operand(reg));
1995 } 1797 }
1996 1798
1997
1998 void Assembler::divl(Register reg) { 1799 void Assembler::divl(Register reg) {
1999 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1800 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2000 EmitRegisterREX(reg, REX_NONE); 1801 EmitRegisterREX(reg, REX_NONE);
2001 EmitUint8(0xF7); 1802 EmitUint8(0xF7);
2002 EmitOperand(6, Operand(reg)); 1803 EmitOperand(6, Operand(reg));
2003 } 1804 }
2004 1805
2005
2006 void Assembler::idivq(Register reg) { 1806 void Assembler::idivq(Register reg) {
2007 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1807 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2008 EmitRegisterREX(reg, REX_W); 1808 EmitRegisterREX(reg, REX_W);
2009 EmitUint8(0xF7); 1809 EmitUint8(0xF7);
2010 EmitOperand(7, Operand(reg)); 1810 EmitOperand(7, Operand(reg));
2011 } 1811 }
2012 1812
2013
2014 void Assembler::divq(Register reg) { 1813 void Assembler::divq(Register reg) {
2015 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1814 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2016 EmitRegisterREX(reg, REX_W); 1815 EmitRegisterREX(reg, REX_W);
2017 EmitUint8(0xF7); 1816 EmitUint8(0xF7);
2018 EmitOperand(6, Operand(reg)); 1817 EmitOperand(6, Operand(reg));
2019 } 1818 }
2020 1819
2021
2022 void Assembler::imull(Register dst, Register src) { 1820 void Assembler::imull(Register dst, Register src) {
2023 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1821 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2024 Operand operand(src); 1822 Operand operand(src);
2025 EmitOperandREX(dst, operand, REX_NONE); 1823 EmitOperandREX(dst, operand, REX_NONE);
2026 EmitUint8(0x0F); 1824 EmitUint8(0x0F);
2027 EmitUint8(0xAF); 1825 EmitUint8(0xAF);
2028 EmitOperand(dst & 7, Operand(src)); 1826 EmitOperand(dst & 7, Operand(src));
2029 } 1827 }
2030 1828
2031
2032 void Assembler::imull(Register reg, const Immediate& imm) { 1829 void Assembler::imull(Register reg, const Immediate& imm) {
2033 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1830 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2034 Operand operand(reg); 1831 Operand operand(reg);
2035 EmitOperandREX(reg, operand, REX_NONE); 1832 EmitOperandREX(reg, operand, REX_NONE);
2036 EmitUint8(0x69); 1833 EmitUint8(0x69);
2037 EmitOperand(reg & 7, Operand(reg)); 1834 EmitOperand(reg & 7, Operand(reg));
2038 EmitImmediate(imm); 1835 EmitImmediate(imm);
2039 } 1836 }
2040 1837
2041
2042 void Assembler::mull(Register reg) { 1838 void Assembler::mull(Register reg) {
2043 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1839 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2044 EmitRegisterREX(reg, REX_NONE); 1840 EmitRegisterREX(reg, REX_NONE);
2045 EmitUint8(0xF7); 1841 EmitUint8(0xF7);
2046 EmitOperand(4, Operand(reg)); 1842 EmitOperand(4, Operand(reg));
2047 } 1843 }
2048 1844
2049
2050 void Assembler::imulq(Register dst, Register src) { 1845 void Assembler::imulq(Register dst, Register src) {
2051 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1846 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2052 Operand operand(src); 1847 Operand operand(src);
2053 EmitOperandREX(dst, operand, REX_W); 1848 EmitOperandREX(dst, operand, REX_W);
2054 EmitUint8(0x0F); 1849 EmitUint8(0x0F);
2055 EmitUint8(0xAF); 1850 EmitUint8(0xAF);
2056 EmitOperand(dst & 7, operand); 1851 EmitOperand(dst & 7, operand);
2057 } 1852 }
2058 1853
2059
2060 void Assembler::imulq(Register reg, const Immediate& imm) { 1854 void Assembler::imulq(Register reg, const Immediate& imm) {
2061 if (imm.is_int32()) { 1855 if (imm.is_int32()) {
2062 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1856 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2063 Operand operand(reg); 1857 Operand operand(reg);
2064 EmitOperandREX(reg, operand, REX_W); 1858 EmitOperandREX(reg, operand, REX_W);
2065 EmitUint8(0x69); 1859 EmitUint8(0x69);
2066 EmitOperand(reg & 7, Operand(reg)); 1860 EmitOperand(reg & 7, Operand(reg));
2067 EmitImmediate(imm); 1861 EmitImmediate(imm);
2068 } else { 1862 } else {
2069 ASSERT(reg != TMP); 1863 ASSERT(reg != TMP);
2070 movq(TMP, imm); 1864 movq(TMP, imm);
2071 imulq(reg, TMP); 1865 imulq(reg, TMP);
2072 } 1866 }
2073 } 1867 }
2074 1868
2075
2076 void Assembler::MulImmediate(Register reg, const Immediate& imm) { 1869 void Assembler::MulImmediate(Register reg, const Immediate& imm) {
2077 if (imm.is_int32()) { 1870 if (imm.is_int32()) {
2078 imulq(reg, imm); 1871 imulq(reg, imm);
2079 } else { 1872 } else {
2080 ASSERT(reg != TMP); 1873 ASSERT(reg != TMP);
2081 LoadImmediate(TMP, imm); 1874 LoadImmediate(TMP, imm);
2082 imulq(reg, TMP); 1875 imulq(reg, TMP);
2083 } 1876 }
2084 } 1877 }
2085 1878
2086
2087 void Assembler::imulq(Register dst, const Address& address) { 1879 void Assembler::imulq(Register dst, const Address& address) {
2088 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1880 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2089 EmitOperandREX(dst, address, REX_W); 1881 EmitOperandREX(dst, address, REX_W);
2090 EmitUint8(0x0F); 1882 EmitUint8(0x0F);
2091 EmitUint8(0xAF); 1883 EmitUint8(0xAF);
2092 EmitOperand(dst & 7, address); 1884 EmitOperand(dst & 7, address);
2093 } 1885 }
2094 1886
2095
2096 void Assembler::mulq(Register reg) { 1887 void Assembler::mulq(Register reg) {
2097 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1888 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2098 EmitRegisterREX(reg, REX_W); 1889 EmitRegisterREX(reg, REX_W);
2099 EmitUint8(0xF7); 1890 EmitUint8(0xF7);
2100 EmitOperand(4, Operand(reg)); 1891 EmitOperand(4, Operand(reg));
2101 } 1892 }
2102 1893
2103
2104 void Assembler::subq(Register dst, Register src) { 1894 void Assembler::subq(Register dst, Register src) {
2105 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1895 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2106 Operand operand(src); 1896 Operand operand(src);
2107 EmitOperandREX(dst, operand, REX_W); 1897 EmitOperandREX(dst, operand, REX_W);
2108 EmitUint8(0x2B); 1898 EmitUint8(0x2B);
2109 EmitOperand(dst & 7, operand); 1899 EmitOperand(dst & 7, operand);
2110 } 1900 }
2111 1901
2112
2113 void Assembler::subq(Register reg, const Immediate& imm) { 1902 void Assembler::subq(Register reg, const Immediate& imm) {
2114 if (imm.is_int32()) { 1903 if (imm.is_int32()) {
2115 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1904 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2116 EmitRegisterREX(reg, REX_W); 1905 EmitRegisterREX(reg, REX_W);
2117 EmitComplex(5, Operand(reg), imm); 1906 EmitComplex(5, Operand(reg), imm);
2118 } else { 1907 } else {
2119 ASSERT(reg != TMP); 1908 ASSERT(reg != TMP);
2120 movq(TMP, imm); 1909 movq(TMP, imm);
2121 subq(reg, TMP); 1910 subq(reg, TMP);
2122 } 1911 }
2123 } 1912 }
2124 1913
2125
2126 void Assembler::subq(Register reg, const Address& address) { 1914 void Assembler::subq(Register reg, const Address& address) {
2127 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1915 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2128 EmitOperandREX(reg, address, REX_W); 1916 EmitOperandREX(reg, address, REX_W);
2129 EmitUint8(0x2B); 1917 EmitUint8(0x2B);
2130 EmitOperand(reg & 7, address); 1918 EmitOperand(reg & 7, address);
2131 } 1919 }
2132 1920
2133
2134 void Assembler::subq(const Address& address, Register reg) { 1921 void Assembler::subq(const Address& address, Register reg) {
2135 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1922 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2136 EmitOperandREX(reg, address, REX_W); 1923 EmitOperandREX(reg, address, REX_W);
2137 EmitUint8(0x29); 1924 EmitUint8(0x29);
2138 EmitOperand(reg & 7, address); 1925 EmitOperand(reg & 7, address);
2139 } 1926 }
2140 1927
2141
2142 void Assembler::subq(const Address& address, const Immediate& imm) { 1928 void Assembler::subq(const Address& address, const Immediate& imm) {
2143 if (imm.is_int32()) { 1929 if (imm.is_int32()) {
2144 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1930 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2145 EmitOperandREX(0, address, REX_W); 1931 EmitOperandREX(0, address, REX_W);
2146 EmitComplex(5, Operand(address), imm); 1932 EmitComplex(5, Operand(address), imm);
2147 } else { 1933 } else {
2148 movq(TMP, imm); 1934 movq(TMP, imm);
2149 subq(address, TMP); 1935 subq(address, TMP);
2150 } 1936 }
2151 } 1937 }
2152 1938
2153
2154 void Assembler::sbbq(Register dst, Register src) { 1939 void Assembler::sbbq(Register dst, Register src) {
2155 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1940 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2156 Operand operand(src); 1941 Operand operand(src);
2157 EmitOperandREX(dst, operand, REX_W); 1942 EmitOperandREX(dst, operand, REX_W);
2158 EmitUint8(0x1B); 1943 EmitUint8(0x1B);
2159 EmitOperand(dst & 7, operand); 1944 EmitOperand(dst & 7, operand);
2160 } 1945 }
2161 1946
2162
2163 void Assembler::sbbq(Register dst, const Immediate& imm) { 1947 void Assembler::sbbq(Register dst, const Immediate& imm) {
2164 if (imm.is_int32()) { 1948 if (imm.is_int32()) {
2165 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1949 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2166 EmitRegisterREX(dst, REX_W); 1950 EmitRegisterREX(dst, REX_W);
2167 EmitComplex(3, Operand(dst), imm); 1951 EmitComplex(3, Operand(dst), imm);
2168 } else { 1952 } else {
2169 ASSERT(dst != TMP); 1953 ASSERT(dst != TMP);
2170 movq(TMP, imm); 1954 movq(TMP, imm);
2171 sbbq(dst, TMP); 1955 sbbq(dst, TMP);
2172 } 1956 }
2173 } 1957 }
2174 1958
2175
2176 void Assembler::sbbq(Register dst, const Address& address) { 1959 void Assembler::sbbq(Register dst, const Address& address) {
2177 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1960 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2178 EmitOperandREX(dst, address, REX_W); 1961 EmitOperandREX(dst, address, REX_W);
2179 EmitUint8(0x1B); 1962 EmitUint8(0x1B);
2180 EmitOperand(dst & 7, address); 1963 EmitOperand(dst & 7, address);
2181 } 1964 }
2182 1965
2183
2184 void Assembler::shll(Register reg, const Immediate& imm) { 1966 void Assembler::shll(Register reg, const Immediate& imm) {
2185 EmitGenericShift(false, 4, reg, imm); 1967 EmitGenericShift(false, 4, reg, imm);
2186 } 1968 }
2187 1969
2188
2189 void Assembler::shll(Register operand, Register shifter) { 1970 void Assembler::shll(Register operand, Register shifter) {
2190 EmitGenericShift(false, 4, operand, shifter); 1971 EmitGenericShift(false, 4, operand, shifter);
2191 } 1972 }
2192 1973
2193
2194 void Assembler::shrl(Register reg, const Immediate& imm) { 1974 void Assembler::shrl(Register reg, const Immediate& imm) {
2195 EmitGenericShift(false, 5, reg, imm); 1975 EmitGenericShift(false, 5, reg, imm);
2196 } 1976 }
2197 1977
2198
2199 void Assembler::shrl(Register operand, Register shifter) { 1978 void Assembler::shrl(Register operand, Register shifter) {
2200 EmitGenericShift(false, 5, operand, shifter); 1979 EmitGenericShift(false, 5, operand, shifter);
2201 } 1980 }
2202 1981
2203
2204 void Assembler::sarl(Register reg, const Immediate& imm) { 1982 void Assembler::sarl(Register reg, const Immediate& imm) {
2205 EmitGenericShift(false, 7, reg, imm); 1983 EmitGenericShift(false, 7, reg, imm);
2206 } 1984 }
2207 1985
2208
2209 void Assembler::sarl(Register operand, Register shifter) { 1986 void Assembler::sarl(Register operand, Register shifter) {
2210 EmitGenericShift(false, 7, operand, shifter); 1987 EmitGenericShift(false, 7, operand, shifter);
2211 } 1988 }
2212 1989
2213
2214 void Assembler::shldl(Register dst, Register src, const Immediate& imm) { 1990 void Assembler::shldl(Register dst, Register src, const Immediate& imm) {
2215 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1991 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2216 ASSERT(imm.is_int8()); 1992 ASSERT(imm.is_int8());
2217 Operand operand(dst); 1993 Operand operand(dst);
2218 EmitOperandREX(src, operand, REX_NONE); 1994 EmitOperandREX(src, operand, REX_NONE);
2219 EmitUint8(0x0F); 1995 EmitUint8(0x0F);
2220 EmitUint8(0xA4); 1996 EmitUint8(0xA4);
2221 EmitOperand(src & 7, operand); 1997 EmitOperand(src & 7, operand);
2222 EmitUint8(imm.value() & 0xFF); 1998 EmitUint8(imm.value() & 0xFF);
2223 } 1999 }
2224 2000
2225
2226 void Assembler::shlq(Register reg, const Immediate& imm) { 2001 void Assembler::shlq(Register reg, const Immediate& imm) {
2227 EmitGenericShift(true, 4, reg, imm); 2002 EmitGenericShift(true, 4, reg, imm);
2228 } 2003 }
2229 2004
2230
2231 void Assembler::shlq(Register operand, Register shifter) { 2005 void Assembler::shlq(Register operand, Register shifter) {
2232 EmitGenericShift(true, 4, operand, shifter); 2006 EmitGenericShift(true, 4, operand, shifter);
2233 } 2007 }
2234 2008
2235
2236 void Assembler::shrq(Register reg, const Immediate& imm) { 2009 void Assembler::shrq(Register reg, const Immediate& imm) {
2237 EmitGenericShift(true, 5, reg, imm); 2010 EmitGenericShift(true, 5, reg, imm);
2238 } 2011 }
2239 2012
2240
2241 void Assembler::shrq(Register operand, Register shifter) { 2013 void Assembler::shrq(Register operand, Register shifter) {
2242 EmitGenericShift(true, 5, operand, shifter); 2014 EmitGenericShift(true, 5, operand, shifter);
2243 } 2015 }
2244 2016
2245
2246 void Assembler::sarq(Register reg, const Immediate& imm) { 2017 void Assembler::sarq(Register reg, const Immediate& imm) {
2247 EmitGenericShift(true, 7, reg, imm); 2018 EmitGenericShift(true, 7, reg, imm);
2248 } 2019 }
2249 2020
2250
2251 void Assembler::sarq(Register operand, Register shifter) { 2021 void Assembler::sarq(Register operand, Register shifter) {
2252 EmitGenericShift(true, 7, operand, shifter); 2022 EmitGenericShift(true, 7, operand, shifter);
2253 } 2023 }
2254 2024
2255
2256 void Assembler::shldq(Register dst, Register src, const Immediate& imm) { 2025 void Assembler::shldq(Register dst, Register src, const Immediate& imm) {
2257 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2026 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2258 ASSERT(imm.is_int8()); 2027 ASSERT(imm.is_int8());
2259 Operand operand(dst); 2028 Operand operand(dst);
2260 EmitOperandREX(src, operand, REX_W); 2029 EmitOperandREX(src, operand, REX_W);
2261 EmitUint8(0x0F); 2030 EmitUint8(0x0F);
2262 EmitUint8(0xA4); 2031 EmitUint8(0xA4);
2263 EmitOperand(src & 7, operand); 2032 EmitOperand(src & 7, operand);
2264 EmitUint8(imm.value() & 0xFF); 2033 EmitUint8(imm.value() & 0xFF);
2265 } 2034 }
2266 2035
2267
2268 void Assembler::shldq(Register dst, Register src, Register shifter) { 2036 void Assembler::shldq(Register dst, Register src, Register shifter) {
2269 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2037 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2270 ASSERT(shifter == RCX); 2038 ASSERT(shifter == RCX);
2271 Operand operand(dst); 2039 Operand operand(dst);
2272 EmitOperandREX(src, operand, REX_W); 2040 EmitOperandREX(src, operand, REX_W);
2273 EmitUint8(0x0F); 2041 EmitUint8(0x0F);
2274 EmitUint8(0xA5); 2042 EmitUint8(0xA5);
2275 EmitOperand(src & 7, operand); 2043 EmitOperand(src & 7, operand);
2276 } 2044 }
2277 2045
2278
2279 void Assembler::shrdq(Register dst, Register src, Register shifter) { 2046 void Assembler::shrdq(Register dst, Register src, Register shifter) {
2280 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2047 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2281 ASSERT(shifter == RCX); 2048 ASSERT(shifter == RCX);
2282 Operand operand(dst); 2049 Operand operand(dst);
2283 EmitOperandREX(src, operand, REX_W); 2050 EmitOperandREX(src, operand, REX_W);
2284 EmitUint8(0x0F); 2051 EmitUint8(0x0F);
2285 EmitUint8(0xAD); 2052 EmitUint8(0xAD);
2286 EmitOperand(src & 7, operand); 2053 EmitOperand(src & 7, operand);
2287 } 2054 }
2288 2055
2289
2290 void Assembler::incl(const Address& address) { 2056 void Assembler::incl(const Address& address) {
2291 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2057 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2292 Operand operand(address); 2058 Operand operand(address);
2293 EmitOperandREX(0, operand, REX_NONE); 2059 EmitOperandREX(0, operand, REX_NONE);
2294 EmitUint8(0xFF); 2060 EmitUint8(0xFF);
2295 EmitOperand(0, operand); 2061 EmitOperand(0, operand);
2296 } 2062 }
2297 2063
2298
2299 void Assembler::decl(const Address& address) { 2064 void Assembler::decl(const Address& address) {
2300 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2065 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2301 Operand operand(address); 2066 Operand operand(address);
2302 EmitOperandREX(1, operand, REX_NONE); 2067 EmitOperandREX(1, operand, REX_NONE);
2303 EmitUint8(0xFF); 2068 EmitUint8(0xFF);
2304 EmitOperand(1, operand); 2069 EmitOperand(1, operand);
2305 } 2070 }
2306 2071
2307
2308 void Assembler::incq(Register reg) { 2072 void Assembler::incq(Register reg) {
2309 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2073 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2310 Operand operand(reg); 2074 Operand operand(reg);
2311 EmitOperandREX(0, operand, REX_W); 2075 EmitOperandREX(0, operand, REX_W);
2312 EmitUint8(0xFF); 2076 EmitUint8(0xFF);
2313 EmitOperand(0, operand); 2077 EmitOperand(0, operand);
2314 } 2078 }
2315 2079
2316
2317 void Assembler::incq(const Address& address) { 2080 void Assembler::incq(const Address& address) {
2318 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2081 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2319 Operand operand(address); 2082 Operand operand(address);
2320 EmitOperandREX(0, operand, REX_W); 2083 EmitOperandREX(0, operand, REX_W);
2321 EmitUint8(0xFF); 2084 EmitUint8(0xFF);
2322 EmitOperand(0, operand); 2085 EmitOperand(0, operand);
2323 } 2086 }
2324 2087
2325
2326 void Assembler::decq(Register reg) { 2088 void Assembler::decq(Register reg) {
2327 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2089 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2328 Operand operand(reg); 2090 Operand operand(reg);
2329 EmitOperandREX(1, operand, REX_W); 2091 EmitOperandREX(1, operand, REX_W);
2330 EmitUint8(0xFF); 2092 EmitUint8(0xFF);
2331 EmitOperand(1, operand); 2093 EmitOperand(1, operand);
2332 } 2094 }
2333 2095
2334
2335 void Assembler::decq(const Address& address) { 2096 void Assembler::decq(const Address& address) {
2336 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2097 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2337 Operand operand(address); 2098 Operand operand(address);
2338 EmitOperandREX(1, operand, REX_W); 2099 EmitOperandREX(1, operand, REX_W);
2339 EmitUint8(0xFF); 2100 EmitUint8(0xFF);
2340 EmitOperand(1, operand); 2101 EmitOperand(1, operand);
2341 } 2102 }
2342 2103
2343
2344 void Assembler::negl(Register reg) { 2104 void Assembler::negl(Register reg) {
2345 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2105 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2346 EmitRegisterREX(reg, REX_NONE); 2106 EmitRegisterREX(reg, REX_NONE);
2347 EmitUint8(0xF7); 2107 EmitUint8(0xF7);
2348 EmitOperand(3, Operand(reg)); 2108 EmitOperand(3, Operand(reg));
2349 } 2109 }
2350 2110
2351
2352 void Assembler::negq(Register reg) { 2111 void Assembler::negq(Register reg) {
2353 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2112 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2354 EmitRegisterREX(reg, REX_W); 2113 EmitRegisterREX(reg, REX_W);
2355 EmitUint8(0xF7); 2114 EmitUint8(0xF7);
2356 EmitOperand(3, Operand(reg)); 2115 EmitOperand(3, Operand(reg));
2357 } 2116 }
2358 2117
2359
2360 void Assembler::notl(Register reg) { 2118 void Assembler::notl(Register reg) {
2361 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2119 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2362 EmitRegisterREX(reg, REX_NONE); 2120 EmitRegisterREX(reg, REX_NONE);
2363 EmitUint8(0xF7); 2121 EmitUint8(0xF7);
2364 EmitUint8(0xD0 | (reg & 7)); 2122 EmitUint8(0xD0 | (reg & 7));
2365 } 2123 }
2366 2124
2367
2368 void Assembler::notq(Register reg) { 2125 void Assembler::notq(Register reg) {
2369 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2126 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2370 EmitRegisterREX(reg, REX_W); 2127 EmitRegisterREX(reg, REX_W);
2371 EmitUint8(0xF7); 2128 EmitUint8(0xF7);
2372 EmitUint8(0xD0 | (reg & 7)); 2129 EmitUint8(0xD0 | (reg & 7));
2373 } 2130 }
2374 2131
2375
2376 void Assembler::bsrq(Register dst, Register src) { 2132 void Assembler::bsrq(Register dst, Register src) {
2377 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2133 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2378 Operand operand(src); 2134 Operand operand(src);
2379 EmitOperandREX(dst, operand, REX_W); 2135 EmitOperandREX(dst, operand, REX_W);
2380 EmitUint8(0x0F); 2136 EmitUint8(0x0F);
2381 EmitUint8(0xBD); 2137 EmitUint8(0xBD);
2382 EmitOperand(dst & 7, operand); 2138 EmitOperand(dst & 7, operand);
2383 } 2139 }
2384 2140
2385
2386 void Assembler::btq(Register base, Register offset) { 2141 void Assembler::btq(Register base, Register offset) {
2387 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2142 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2388 Operand operand(base); 2143 Operand operand(base);
2389 EmitOperandREX(offset, operand, REX_W); 2144 EmitOperandREX(offset, operand, REX_W);
2390 EmitUint8(0x0F); 2145 EmitUint8(0x0F);
2391 EmitUint8(0xA3); 2146 EmitUint8(0xA3);
2392 EmitOperand(offset & 7, operand); 2147 EmitOperand(offset & 7, operand);
2393 } 2148 }
2394 2149
2395
2396 void Assembler::enter(const Immediate& imm) { 2150 void Assembler::enter(const Immediate& imm) {
2397 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2151 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2398 EmitUint8(0xC8); 2152 EmitUint8(0xC8);
2399 ASSERT(imm.is_uint16()); 2153 ASSERT(imm.is_uint16());
2400 EmitUint8(imm.value() & 0xFF); 2154 EmitUint8(imm.value() & 0xFF);
2401 EmitUint8((imm.value() >> 8) & 0xFF); 2155 EmitUint8((imm.value() >> 8) & 0xFF);
2402 EmitUint8(0x00); 2156 EmitUint8(0x00);
2403 } 2157 }
2404 2158
2405
2406 void Assembler::leave() { 2159 void Assembler::leave() {
2407 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2160 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2408 EmitUint8(0xC9); 2161 EmitUint8(0xC9);
2409 } 2162 }
2410 2163
2411
2412 void Assembler::ret() { 2164 void Assembler::ret() {
2413 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2165 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2414 EmitUint8(0xC3); 2166 EmitUint8(0xC3);
2415 } 2167 }
2416 2168
2417
2418 void Assembler::nop(int size) { 2169 void Assembler::nop(int size) {
2419 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2170 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2420 // There are nops up to size 15, but for now just provide up to size 8. 2171 // There are nops up to size 15, but for now just provide up to size 8.
2421 ASSERT(0 < size && size <= MAX_NOP_SIZE); 2172 ASSERT(0 < size && size <= MAX_NOP_SIZE);
2422 switch (size) { 2173 switch (size) {
2423 case 1: 2174 case 1:
2424 EmitUint8(0x90); 2175 EmitUint8(0x90);
2425 break; 2176 break;
2426 case 2: 2177 case 2:
2427 EmitUint8(0x66); 2178 EmitUint8(0x66);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2470 EmitUint8(0x00); 2221 EmitUint8(0x00);
2471 EmitUint8(0x00); 2222 EmitUint8(0x00);
2472 EmitUint8(0x00); 2223 EmitUint8(0x00);
2473 EmitUint8(0x00); 2224 EmitUint8(0x00);
2474 break; 2225 break;
2475 default: 2226 default:
2476 UNIMPLEMENTED(); 2227 UNIMPLEMENTED();
2477 } 2228 }
2478 } 2229 }
2479 2230
2480
2481 void Assembler::int3() { 2231 void Assembler::int3() {
2482 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2232 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2483 EmitUint8(0xCC); 2233 EmitUint8(0xCC);
2484 } 2234 }
2485 2235
2486
2487 void Assembler::hlt() { 2236 void Assembler::hlt() {
2488 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2237 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2489 EmitUint8(0xF4); 2238 EmitUint8(0xF4);
2490 } 2239 }
2491 2240
2492
2493 void Assembler::j(Condition condition, Label* label, bool near) { 2241 void Assembler::j(Condition condition, Label* label, bool near) {
2494 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2242 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2495 if (label->IsBound()) { 2243 if (label->IsBound()) {
2496 static const int kShortSize = 2; 2244 static const int kShortSize = 2;
2497 static const int kLongSize = 6; 2245 static const int kLongSize = 6;
2498 intptr_t offset = label->Position() - buffer_.Size(); 2246 intptr_t offset = label->Position() - buffer_.Size();
2499 ASSERT(offset <= 0); 2247 ASSERT(offset <= 0);
2500 if (Utils::IsInt(8, offset - kShortSize)) { 2248 if (Utils::IsInt(8, offset - kShortSize)) {
2501 EmitUint8(0x70 + condition); 2249 EmitUint8(0x70 + condition);
2502 EmitUint8((offset - kShortSize) & 0xFF); 2250 EmitUint8((offset - kShortSize) & 0xFF);
2503 } else { 2251 } else {
2504 EmitUint8(0x0F); 2252 EmitUint8(0x0F);
2505 EmitUint8(0x80 + condition); 2253 EmitUint8(0x80 + condition);
2506 EmitInt32(offset - kLongSize); 2254 EmitInt32(offset - kLongSize);
2507 } 2255 }
2508 } else if (near) { 2256 } else if (near) {
2509 EmitUint8(0x70 + condition); 2257 EmitUint8(0x70 + condition);
2510 EmitNearLabelLink(label); 2258 EmitNearLabelLink(label);
2511 } else { 2259 } else {
2512 EmitUint8(0x0F); 2260 EmitUint8(0x0F);
2513 EmitUint8(0x80 + condition); 2261 EmitUint8(0x80 + condition);
2514 EmitLabelLink(label); 2262 EmitLabelLink(label);
2515 } 2263 }
2516 } 2264 }
2517 2265
2518
2519 void Assembler::J(Condition condition, 2266 void Assembler::J(Condition condition,
2520 const StubEntry& stub_entry, 2267 const StubEntry& stub_entry,
2521 Register pp) { 2268 Register pp) {
2522 Label no_jump; 2269 Label no_jump;
2523 // Negate condition. 2270 // Negate condition.
2524 j(static_cast<Condition>(condition ^ 1), &no_jump, kNearJump); 2271 j(static_cast<Condition>(condition ^ 1), &no_jump, kNearJump);
2525 Jmp(stub_entry, pp); 2272 Jmp(stub_entry, pp);
2526 Bind(&no_jump); 2273 Bind(&no_jump);
2527 } 2274 }
2528 2275
2529
2530 void Assembler::jmp(Register reg) { 2276 void Assembler::jmp(Register reg) {
2531 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2277 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2532 Operand operand(reg); 2278 Operand operand(reg);
2533 EmitOperandREX(4, operand, REX_NONE); 2279 EmitOperandREX(4, operand, REX_NONE);
2534 EmitUint8(0xFF); 2280 EmitUint8(0xFF);
2535 EmitOperand(4, operand); 2281 EmitOperand(4, operand);
2536 } 2282 }
2537 2283
2538
2539 void Assembler::jmp(const Address& dst) { 2284 void Assembler::jmp(const Address& dst) {
2540 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2285 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2541 EmitOperandREX(4, dst, REX_NONE); 2286 EmitOperandREX(4, dst, REX_NONE);
2542 EmitUint8(0xFF); 2287 EmitUint8(0xFF);
2543 EmitOperand(4, dst); 2288 EmitOperand(4, dst);
2544 } 2289 }
2545 2290
2546
2547 void Assembler::jmp(Label* label, bool near) { 2291 void Assembler::jmp(Label* label, bool near) {
2548 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2292 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2549 if (label->IsBound()) { 2293 if (label->IsBound()) {
2550 static const int kShortSize = 2; 2294 static const int kShortSize = 2;
2551 static const int kLongSize = 5; 2295 static const int kLongSize = 5;
2552 intptr_t offset = label->Position() - buffer_.Size(); 2296 intptr_t offset = label->Position() - buffer_.Size();
2553 ASSERT(offset <= 0); 2297 ASSERT(offset <= 0);
2554 if (Utils::IsInt(8, offset - kShortSize)) { 2298 if (Utils::IsInt(8, offset - kShortSize)) {
2555 EmitUint8(0xEB); 2299 EmitUint8(0xEB);
2556 EmitUint8((offset - kShortSize) & 0xFF); 2300 EmitUint8((offset - kShortSize) & 0xFF);
2557 } else { 2301 } else {
2558 EmitUint8(0xE9); 2302 EmitUint8(0xE9);
2559 EmitInt32(offset - kLongSize); 2303 EmitInt32(offset - kLongSize);
2560 } 2304 }
2561 } else if (near) { 2305 } else if (near) {
2562 EmitUint8(0xEB); 2306 EmitUint8(0xEB);
2563 EmitNearLabelLink(label); 2307 EmitNearLabelLink(label);
2564 } else { 2308 } else {
2565 EmitUint8(0xE9); 2309 EmitUint8(0xE9);
2566 EmitLabelLink(label); 2310 EmitLabelLink(label);
2567 } 2311 }
2568 } 2312 }
2569 2313
2570
2571 void Assembler::jmp(const ExternalLabel* label) { 2314 void Assembler::jmp(const ExternalLabel* label) {
2572 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. 2315 { // Encode movq(TMP, Immediate(label->address())), but always as imm64.
2573 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2316 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2574 EmitRegisterREX(TMP, REX_W); 2317 EmitRegisterREX(TMP, REX_W);
2575 EmitUint8(0xB8 | (TMP & 7)); 2318 EmitUint8(0xB8 | (TMP & 7));
2576 EmitInt64(label->address()); 2319 EmitInt64(label->address());
2577 } 2320 }
2578 jmp(TMP); 2321 jmp(TMP);
2579 } 2322 }
2580 2323
2581
2582 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) { 2324 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) {
2583 ASSERT((pp != PP) || constant_pool_allowed()); 2325 ASSERT((pp != PP) || constant_pool_allowed());
2584 const Code& target = Code::ZoneHandle(stub_entry.code()); 2326 const Code& target = Code::ZoneHandle(stub_entry.code());
2585 const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable); 2327 const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable);
2586 const int32_t offset = ObjectPool::element_offset(idx); 2328 const int32_t offset = ObjectPool::element_offset(idx);
2587 movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); 2329 movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
2588 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); 2330 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
2589 jmp(TMP); 2331 jmp(TMP);
2590 } 2332 }
2591 2333
2592
2593 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) { 2334 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) {
2594 ASSERT((pp != PP) || constant_pool_allowed()); 2335 ASSERT((pp != PP) || constant_pool_allowed());
2595 const Code& target = Code::ZoneHandle(stub_entry.code()); 2336 const Code& target = Code::ZoneHandle(stub_entry.code());
2596 const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable); 2337 const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable);
2597 const int32_t offset = ObjectPool::element_offset(idx); 2338 const int32_t offset = ObjectPool::element_offset(idx);
2598 movq(CODE_REG, FieldAddress(pp, offset)); 2339 movq(CODE_REG, FieldAddress(pp, offset));
2599 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); 2340 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
2600 jmp(TMP); 2341 jmp(TMP);
2601 } 2342 }
2602 2343
2603
2604 void Assembler::lock() { 2344 void Assembler::lock() {
2605 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2345 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2606 EmitUint8(0xF0); 2346 EmitUint8(0xF0);
2607 } 2347 }
2608 2348
2609
2610 void Assembler::cmpxchgl(const Address& address, Register reg) { 2349 void Assembler::cmpxchgl(const Address& address, Register reg) {
2611 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2350 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2612 EmitOperandREX(reg, address, REX_NONE); 2351 EmitOperandREX(reg, address, REX_NONE);
2613 EmitUint8(0x0F); 2352 EmitUint8(0x0F);
2614 EmitUint8(0xB1); 2353 EmitUint8(0xB1);
2615 EmitOperand(reg & 7, address); 2354 EmitOperand(reg & 7, address);
2616 } 2355 }
2617 2356
2618
2619 void Assembler::cmpxchgq(const Address& address, Register reg) { 2357 void Assembler::cmpxchgq(const Address& address, Register reg) {
2620 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2358 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2621 EmitOperandREX(reg, address, REX_W); 2359 EmitOperandREX(reg, address, REX_W);
2622 EmitUint8(0x0F); 2360 EmitUint8(0x0F);
2623 EmitUint8(0xB1); 2361 EmitUint8(0xB1);
2624 EmitOperand(reg & 7, address); 2362 EmitOperand(reg & 7, address);
2625 } 2363 }
2626 2364
2627
2628 void Assembler::cpuid() { 2365 void Assembler::cpuid() {
2629 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2366 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2630 EmitUint8(0x0F); 2367 EmitUint8(0x0F);
2631 EmitUint8(0xA2); 2368 EmitUint8(0xA2);
2632 } 2369 }
2633 2370
2634
2635 void Assembler::CompareRegisters(Register a, Register b) { 2371 void Assembler::CompareRegisters(Register a, Register b) {
2636 cmpq(a, b); 2372 cmpq(a, b);
2637 } 2373 }
2638 2374
2639
2640 void Assembler::MoveRegister(Register to, Register from) { 2375 void Assembler::MoveRegister(Register to, Register from) {
2641 if (to != from) { 2376 if (to != from) {
2642 movq(to, from); 2377 movq(to, from);
2643 } 2378 }
2644 } 2379 }
2645 2380
2646
2647 void Assembler::PopRegister(Register r) { 2381 void Assembler::PopRegister(Register r) {
2648 popq(r); 2382 popq(r);
2649 } 2383 }
2650 2384
2651
2652 void Assembler::AddImmediate(Register reg, const Immediate& imm) { 2385 void Assembler::AddImmediate(Register reg, const Immediate& imm) {
2653 const int64_t value = imm.value(); 2386 const int64_t value = imm.value();
2654 if (value == 0) { 2387 if (value == 0) {
2655 return; 2388 return;
2656 } 2389 }
2657 if ((value > 0) || (value == kMinInt64)) { 2390 if ((value > 0) || (value == kMinInt64)) {
2658 if (value == 1) { 2391 if (value == 1) {
2659 incq(reg); 2392 incq(reg);
2660 } else { 2393 } else {
2661 if (imm.is_int32()) { 2394 if (imm.is_int32()) {
2662 addq(reg, imm); 2395 addq(reg, imm);
2663 } else { 2396 } else {
2664 ASSERT(reg != TMP); 2397 ASSERT(reg != TMP);
2665 LoadImmediate(TMP, imm); 2398 LoadImmediate(TMP, imm);
2666 addq(reg, TMP); 2399 addq(reg, TMP);
2667 } 2400 }
2668 } 2401 }
2669 } else { 2402 } else {
2670 SubImmediate(reg, Immediate(-value)); 2403 SubImmediate(reg, Immediate(-value));
2671 } 2404 }
2672 } 2405 }
2673 2406
2674
2675 void Assembler::AddImmediate(const Address& address, const Immediate& imm) { 2407 void Assembler::AddImmediate(const Address& address, const Immediate& imm) {
2676 const int64_t value = imm.value(); 2408 const int64_t value = imm.value();
2677 if (value == 0) { 2409 if (value == 0) {
2678 return; 2410 return;
2679 } 2411 }
2680 if ((value > 0) || (value == kMinInt64)) { 2412 if ((value > 0) || (value == kMinInt64)) {
2681 if (value == 1) { 2413 if (value == 1) {
2682 incq(address); 2414 incq(address);
2683 } else { 2415 } else {
2684 if (imm.is_int32()) { 2416 if (imm.is_int32()) {
2685 addq(address, imm); 2417 addq(address, imm);
2686 } else { 2418 } else {
2687 LoadImmediate(TMP, imm); 2419 LoadImmediate(TMP, imm);
2688 addq(address, TMP); 2420 addq(address, TMP);
2689 } 2421 }
2690 } 2422 }
2691 } else { 2423 } else {
2692 SubImmediate(address, Immediate(-value)); 2424 SubImmediate(address, Immediate(-value));
2693 } 2425 }
2694 } 2426 }
2695 2427
2696
2697 void Assembler::SubImmediate(Register reg, const Immediate& imm) { 2428 void Assembler::SubImmediate(Register reg, const Immediate& imm) {
2698 const int64_t value = imm.value(); 2429 const int64_t value = imm.value();
2699 if (value == 0) { 2430 if (value == 0) {
2700 return; 2431 return;
2701 } 2432 }
2702 if ((value > 0) || (value == kMinInt64)) { 2433 if ((value > 0) || (value == kMinInt64)) {
2703 if (value == 1) { 2434 if (value == 1) {
2704 decq(reg); 2435 decq(reg);
2705 } else { 2436 } else {
2706 if (imm.is_int32()) { 2437 if (imm.is_int32()) {
2707 subq(reg, imm); 2438 subq(reg, imm);
2708 } else { 2439 } else {
2709 ASSERT(reg != TMP); 2440 ASSERT(reg != TMP);
2710 LoadImmediate(TMP, imm); 2441 LoadImmediate(TMP, imm);
2711 subq(reg, TMP); 2442 subq(reg, TMP);
2712 } 2443 }
2713 } 2444 }
2714 } else { 2445 } else {
2715 AddImmediate(reg, Immediate(-value)); 2446 AddImmediate(reg, Immediate(-value));
2716 } 2447 }
2717 } 2448 }
2718 2449
2719
2720 void Assembler::SubImmediate(const Address& address, const Immediate& imm) { 2450 void Assembler::SubImmediate(const Address& address, const Immediate& imm) {
2721 const int64_t value = imm.value(); 2451 const int64_t value = imm.value();
2722 if (value == 0) { 2452 if (value == 0) {
2723 return; 2453 return;
2724 } 2454 }
2725 if ((value > 0) || (value == kMinInt64)) { 2455 if ((value > 0) || (value == kMinInt64)) {
2726 if (value == 1) { 2456 if (value == 1) {
2727 decq(address); 2457 decq(address);
2728 } else { 2458 } else {
2729 if (imm.is_int32()) { 2459 if (imm.is_int32()) {
2730 subq(address, imm); 2460 subq(address, imm);
2731 } else { 2461 } else {
2732 LoadImmediate(TMP, imm); 2462 LoadImmediate(TMP, imm);
2733 subq(address, TMP); 2463 subq(address, TMP);
2734 } 2464 }
2735 } 2465 }
2736 } else { 2466 } else {
2737 AddImmediate(address, Immediate(-value)); 2467 AddImmediate(address, Immediate(-value));
2738 } 2468 }
2739 } 2469 }
2740 2470
2741
2742 void Assembler::Drop(intptr_t stack_elements, Register tmp) { 2471 void Assembler::Drop(intptr_t stack_elements, Register tmp) {
2743 ASSERT(stack_elements >= 0); 2472 ASSERT(stack_elements >= 0);
2744 if (stack_elements <= 4) { 2473 if (stack_elements <= 4) {
2745 for (intptr_t i = 0; i < stack_elements; i++) { 2474 for (intptr_t i = 0; i < stack_elements; i++) {
2746 popq(tmp); 2475 popq(tmp);
2747 } 2476 }
2748 return; 2477 return;
2749 } 2478 }
2750 addq(RSP, Immediate(stack_elements * kWordSize)); 2479 addq(RSP, Immediate(stack_elements * kWordSize));
2751 } 2480 }
2752 2481
2753
2754 bool Assembler::CanLoadFromObjectPool(const Object& object) const { 2482 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
2755 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); 2483 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
2756 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); 2484 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
2757 ASSERT(!Thread::CanLoadFromThread(object)); 2485 ASSERT(!Thread::CanLoadFromThread(object));
2758 if (!constant_pool_allowed()) { 2486 if (!constant_pool_allowed()) {
2759 return false; 2487 return false;
2760 } 2488 }
2761 2489
2762 // TODO(zra, kmillikin): Also load other large immediates from the object 2490 // TODO(zra, kmillikin): Also load other large immediates from the object
2763 // pool 2491 // pool
2764 if (object.IsSmi()) { 2492 if (object.IsSmi()) {
2765 // If the raw smi does not fit into a 32-bit signed int, then we'll keep 2493 // If the raw smi does not fit into a 32-bit signed int, then we'll keep
2766 // the raw value in the object pool. 2494 // the raw value in the object pool.
2767 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); 2495 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw()));
2768 } 2496 }
2769 ASSERT(object.IsNotTemporaryScopedHandle()); 2497 ASSERT(object.IsNotTemporaryScopedHandle());
2770 ASSERT(object.IsOld()); 2498 ASSERT(object.IsOld());
2771 return true; 2499 return true;
2772 } 2500 }
2773 2501
2774
2775 void Assembler::LoadWordFromPoolOffset(Register dst, int32_t offset) { 2502 void Assembler::LoadWordFromPoolOffset(Register dst, int32_t offset) {
2776 ASSERT(constant_pool_allowed()); 2503 ASSERT(constant_pool_allowed());
2777 ASSERT(dst != PP); 2504 ASSERT(dst != PP);
2778 // This sequence must be of fixed size. AddressBaseImm32 2505 // This sequence must be of fixed size. AddressBaseImm32
2779 // forces the address operand to use a fixed-size imm32 encoding. 2506 // forces the address operand to use a fixed-size imm32 encoding.
2780 movq(dst, Address::AddressBaseImm32(PP, offset)); 2507 movq(dst, Address::AddressBaseImm32(PP, offset));
2781 } 2508 }
2782 2509
2783
2784 void Assembler::LoadIsolate(Register dst) { 2510 void Assembler::LoadIsolate(Register dst) {
2785 movq(dst, Address(THR, Thread::isolate_offset())); 2511 movq(dst, Address(THR, Thread::isolate_offset()));
2786 } 2512 }
2787 2513
2788
2789 void Assembler::LoadObjectHelper(Register dst, 2514 void Assembler::LoadObjectHelper(Register dst,
2790 const Object& object, 2515 const Object& object,
2791 bool is_unique) { 2516 bool is_unique) {
2792 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); 2517 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
2793 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); 2518 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
2794 if (Thread::CanLoadFromThread(object)) { 2519 if (Thread::CanLoadFromThread(object)) {
2795 movq(dst, Address(THR, Thread::OffsetFromThread(object))); 2520 movq(dst, Address(THR, Thread::OffsetFromThread(object)));
2796 } else if (CanLoadFromObjectPool(object)) { 2521 } else if (CanLoadFromObjectPool(object)) {
2797 const intptr_t idx = is_unique ? object_pool_wrapper_.AddObject(object) 2522 const intptr_t idx = is_unique ? object_pool_wrapper_.AddObject(object)
2798 : object_pool_wrapper_.FindObject(object); 2523 : object_pool_wrapper_.FindObject(object);
2799 const int32_t offset = ObjectPool::element_offset(idx); 2524 const int32_t offset = ObjectPool::element_offset(idx);
2800 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag); 2525 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
2801 } else { 2526 } else {
2802 ASSERT(object.IsSmi()); 2527 ASSERT(object.IsSmi());
2803 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); 2528 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
2804 } 2529 }
2805 } 2530 }
2806 2531
2807
2808 void Assembler::LoadFunctionFromCalleePool(Register dst, 2532 void Assembler::LoadFunctionFromCalleePool(Register dst,
2809 const Function& function, 2533 const Function& function,
2810 Register new_pp) { 2534 Register new_pp) {
2811 ASSERT(!constant_pool_allowed()); 2535 ASSERT(!constant_pool_allowed());
2812 ASSERT(new_pp != PP); 2536 ASSERT(new_pp != PP);
2813 const intptr_t idx = object_pool_wrapper_.FindObject(function, kNotPatchable); 2537 const intptr_t idx = object_pool_wrapper_.FindObject(function, kNotPatchable);
2814 const int32_t offset = ObjectPool::element_offset(idx); 2538 const int32_t offset = ObjectPool::element_offset(idx);
2815 movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag)); 2539 movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag));
2816 } 2540 }
2817 2541
2818
2819 void Assembler::LoadObject(Register dst, const Object& object) { 2542 void Assembler::LoadObject(Register dst, const Object& object) {
2820 LoadObjectHelper(dst, object, false); 2543 LoadObjectHelper(dst, object, false);
2821 } 2544 }
2822 2545
2823
2824 void Assembler::LoadUniqueObject(Register dst, const Object& object) { 2546 void Assembler::LoadUniqueObject(Register dst, const Object& object) {
2825 LoadObjectHelper(dst, object, true); 2547 LoadObjectHelper(dst, object, true);
2826 } 2548 }
2827 2549
2828
2829 void Assembler::StoreObject(const Address& dst, const Object& object) { 2550 void Assembler::StoreObject(const Address& dst, const Object& object) {
2830 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); 2551 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
2831 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); 2552 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
2832 if (Thread::CanLoadFromThread(object)) { 2553 if (Thread::CanLoadFromThread(object)) {
2833 movq(TMP, Address(THR, Thread::OffsetFromThread(object))); 2554 movq(TMP, Address(THR, Thread::OffsetFromThread(object)));
2834 movq(dst, TMP); 2555 movq(dst, TMP);
2835 } else if (CanLoadFromObjectPool(object)) { 2556 } else if (CanLoadFromObjectPool(object)) {
2836 LoadObject(TMP, object); 2557 LoadObject(TMP, object);
2837 movq(dst, TMP); 2558 movq(dst, TMP);
2838 } else { 2559 } else {
2839 ASSERT(object.IsSmi()); 2560 ASSERT(object.IsSmi());
2840 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); 2561 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
2841 } 2562 }
2842 } 2563 }
2843 2564
2844
2845 void Assembler::PushObject(const Object& object) { 2565 void Assembler::PushObject(const Object& object) {
2846 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); 2566 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
2847 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); 2567 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
2848 if (Thread::CanLoadFromThread(object)) { 2568 if (Thread::CanLoadFromThread(object)) {
2849 pushq(Address(THR, Thread::OffsetFromThread(object))); 2569 pushq(Address(THR, Thread::OffsetFromThread(object)));
2850 } else if (CanLoadFromObjectPool(object)) { 2570 } else if (CanLoadFromObjectPool(object)) {
2851 LoadObject(TMP, object); 2571 LoadObject(TMP, object);
2852 pushq(TMP); 2572 pushq(TMP);
2853 } else { 2573 } else {
2854 ASSERT(object.IsSmi()); 2574 ASSERT(object.IsSmi());
2855 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw()))); 2575 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())));
2856 } 2576 }
2857 } 2577 }
2858 2578
2859
2860 void Assembler::CompareObject(Register reg, const Object& object) { 2579 void Assembler::CompareObject(Register reg, const Object& object) {
2861 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); 2580 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
2862 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); 2581 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
2863 if (Thread::CanLoadFromThread(object)) { 2582 if (Thread::CanLoadFromThread(object)) {
2864 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); 2583 cmpq(reg, Address(THR, Thread::OffsetFromThread(object)));
2865 } else if (CanLoadFromObjectPool(object)) { 2584 } else if (CanLoadFromObjectPool(object)) {
2866 const intptr_t idx = object_pool_wrapper_.FindObject(object, kNotPatchable); 2585 const intptr_t idx = object_pool_wrapper_.FindObject(object, kNotPatchable);
2867 const int32_t offset = ObjectPool::element_offset(idx); 2586 const int32_t offset = ObjectPool::element_offset(idx);
2868 cmpq(reg, Address(PP, offset - kHeapObjectTag)); 2587 cmpq(reg, Address(PP, offset - kHeapObjectTag));
2869 } else { 2588 } else {
2870 ASSERT(object.IsSmi()); 2589 ASSERT(object.IsSmi());
2871 CompareImmediate(reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); 2590 CompareImmediate(reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
2872 } 2591 }
2873 } 2592 }
2874 2593
2875
2876 intptr_t Assembler::FindImmediate(int64_t imm) { 2594 intptr_t Assembler::FindImmediate(int64_t imm) {
2877 return object_pool_wrapper_.FindImmediate(imm); 2595 return object_pool_wrapper_.FindImmediate(imm);
2878 } 2596 }
2879 2597
2880
2881 void Assembler::LoadImmediate(Register reg, const Immediate& imm) { 2598 void Assembler::LoadImmediate(Register reg, const Immediate& imm) {
2882 if (imm.is_int32() || !constant_pool_allowed()) { 2599 if (imm.is_int32() || !constant_pool_allowed()) {
2883 movq(reg, imm); 2600 movq(reg, imm);
2884 } else { 2601 } else {
2885 int32_t offset = ObjectPool::element_offset(FindImmediate(imm.value())); 2602 int32_t offset = ObjectPool::element_offset(FindImmediate(imm.value()));
2886 LoadWordFromPoolOffset(reg, offset - kHeapObjectTag); 2603 LoadWordFromPoolOffset(reg, offset - kHeapObjectTag);
2887 } 2604 }
2888 } 2605 }
2889 2606
2890
2891 void Assembler::MoveImmediate(const Address& dst, const Immediate& imm) { 2607 void Assembler::MoveImmediate(const Address& dst, const Immediate& imm) {
2892 if (imm.is_int32()) { 2608 if (imm.is_int32()) {
2893 movq(dst, imm); 2609 movq(dst, imm);
2894 } else { 2610 } else {
2895 LoadImmediate(TMP, imm); 2611 LoadImmediate(TMP, imm);
2896 movq(dst, TMP); 2612 movq(dst, TMP);
2897 } 2613 }
2898 } 2614 }
2899 2615
2900
2901 // Destroys the value register. 2616 // Destroys the value register.
2902 void Assembler::StoreIntoObjectFilterNoSmi(Register object, 2617 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
2903 Register value, 2618 Register value,
2904 Label* no_update) { 2619 Label* no_update) {
2905 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && 2620 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
2906 (kOldObjectAlignmentOffset == 0)); 2621 (kOldObjectAlignmentOffset == 0));
2907 2622
2908 // Write-barrier triggers if the value is in the new space (has bit set) and 2623 // Write-barrier triggers if the value is in the new space (has bit set) and
2909 // the object is in the old space (has bit cleared). 2624 // the object is in the old space (has bit cleared).
2910 // To check that we could compute value & ~object and skip the write barrier 2625 // To check that we could compute value & ~object and skip the write barrier
2911 // if the bit is not set. However we can't destroy the object. 2626 // if the bit is not set. However we can't destroy the object.
2912 // However to preserve the object we compute negated expression 2627 // However to preserve the object we compute negated expression
2913 // ~value | object instead and skip the write barrier if the bit is set. 2628 // ~value | object instead and skip the write barrier if the bit is set.
2914 notl(value); 2629 notl(value);
2915 orl(value, object); 2630 orl(value, object);
2916 testl(value, Immediate(kNewObjectAlignmentOffset)); 2631 testl(value, Immediate(kNewObjectAlignmentOffset));
2917 j(NOT_ZERO, no_update, Assembler::kNearJump); 2632 j(NOT_ZERO, no_update, Assembler::kNearJump);
2918 } 2633 }
2919 2634
2920
2921 // Destroys the value register. 2635 // Destroys the value register.
2922 void Assembler::StoreIntoObjectFilter(Register object, 2636 void Assembler::StoreIntoObjectFilter(Register object,
2923 Register value, 2637 Register value,
2924 Label* no_update) { 2638 Label* no_update) {
2925 // For the value we are only interested in the new/old bit and the tag bit. 2639 // For the value we are only interested in the new/old bit and the tag bit.
2926 andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag)); 2640 andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag));
2927 // Shift the tag bit into the carry. 2641 // Shift the tag bit into the carry.
2928 shrl(value, Immediate(1)); 2642 shrl(value, Immediate(1));
2929 // Add the tag bits together, if the value is not a Smi the addition will 2643 // Add the tag bits together, if the value is not a Smi the addition will
2930 // overflow into the next bit, leaving us with a zero low bit. 2644 // overflow into the next bit, leaving us with a zero low bit.
2931 adcl(value, object); 2645 adcl(value, object);
2932 // Mask out higher, uninteresting bits which were polluted by dest. 2646 // Mask out higher, uninteresting bits which were polluted by dest.
2933 andl(value, Immediate(kObjectAlignment - 1)); 2647 andl(value, Immediate(kObjectAlignment - 1));
2934 // Compare with the expected bit pattern. 2648 // Compare with the expected bit pattern.
2935 cmpl(value, Immediate((kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + 2649 cmpl(value, Immediate((kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
2936 kOldObjectAlignmentOffset + kHeapObjectTag)); 2650 kOldObjectAlignmentOffset + kHeapObjectTag));
2937 j(NOT_ZERO, no_update, Assembler::kNearJump); 2651 j(NOT_ZERO, no_update, Assembler::kNearJump);
2938 } 2652 }
2939 2653
2940
2941 void Assembler::StoreIntoObject(Register object, 2654 void Assembler::StoreIntoObject(Register object,
2942 const Address& dest, 2655 const Address& dest,
2943 Register value, 2656 Register value,
2944 bool can_value_be_smi) { 2657 bool can_value_be_smi) {
2945 ASSERT(object != value); 2658 ASSERT(object != value);
2946 movq(dest, value); 2659 movq(dest, value);
2947 Label done; 2660 Label done;
2948 if (can_value_be_smi) { 2661 if (can_value_be_smi) {
2949 StoreIntoObjectFilter(object, value, &done); 2662 StoreIntoObjectFilter(object, value, &done);
2950 } else { 2663 } else {
2951 StoreIntoObjectFilterNoSmi(object, value, &done); 2664 StoreIntoObjectFilterNoSmi(object, value, &done);
2952 } 2665 }
2953 // A store buffer update is required. 2666 // A store buffer update is required.
2954 if (value != RDX) pushq(RDX); 2667 if (value != RDX) pushq(RDX);
2955 if (object != RDX) { 2668 if (object != RDX) {
2956 movq(RDX, object); 2669 movq(RDX, object);
2957 } 2670 }
2958 pushq(CODE_REG); 2671 pushq(CODE_REG);
2959 movq(TMP, Address(THR, Thread::update_store_buffer_entry_point_offset())); 2672 movq(TMP, Address(THR, Thread::update_store_buffer_entry_point_offset()));
2960 movq(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset())); 2673 movq(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
2961 call(TMP); 2674 call(TMP);
2962 2675
2963 popq(CODE_REG); 2676 popq(CODE_REG);
2964 if (value != RDX) popq(RDX); 2677 if (value != RDX) popq(RDX);
2965 Bind(&done); 2678 Bind(&done);
2966 } 2679 }
2967 2680
2968
2969 void Assembler::StoreIntoObjectNoBarrier(Register object, 2681 void Assembler::StoreIntoObjectNoBarrier(Register object,
2970 const Address& dest, 2682 const Address& dest,
2971 Register value) { 2683 Register value) {
2972 movq(dest, value); 2684 movq(dest, value);
2973 #if defined(DEBUG) 2685 #if defined(DEBUG)
2974 Label done; 2686 Label done;
2975 pushq(value); 2687 pushq(value);
2976 StoreIntoObjectFilter(object, value, &done); 2688 StoreIntoObjectFilter(object, value, &done);
2977 Stop("Store buffer update is required"); 2689 Stop("Store buffer update is required");
2978 Bind(&done); 2690 Bind(&done);
2979 popq(value); 2691 popq(value);
2980 #endif // defined(DEBUG) 2692 #endif // defined(DEBUG)
2981 // No store buffer update. 2693 // No store buffer update.
2982 } 2694 }
2983 2695
2984
2985 void Assembler::StoreIntoObjectNoBarrier(Register object, 2696 void Assembler::StoreIntoObjectNoBarrier(Register object,
2986 const Address& dest, 2697 const Address& dest,
2987 const Object& value) { 2698 const Object& value) {
2988 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal()); 2699 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
2989 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal()); 2700 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
2990 StoreObject(dest, value); 2701 StoreObject(dest, value);
2991 } 2702 }
2992 2703
2993
2994 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { 2704 void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
2995 #if defined(DEBUG) 2705 #if defined(DEBUG)
2996 Label done; 2706 Label done;
2997 testq(value, Immediate(kHeapObjectTag)); 2707 testq(value, Immediate(kHeapObjectTag));
2998 j(ZERO, &done); 2708 j(ZERO, &done);
2999 Stop("New value must be Smi."); 2709 Stop("New value must be Smi.");
3000 Bind(&done); 2710 Bind(&done);
3001 #endif // defined(DEBUG) 2711 #endif // defined(DEBUG)
3002 movq(dest, value); 2712 movq(dest, value);
3003 } 2713 }
3004 2714
3005
3006 void Assembler::ZeroInitSmiField(const Address& dest) { 2715 void Assembler::ZeroInitSmiField(const Address& dest) {
3007 Immediate zero(Smi::RawValue(0)); 2716 Immediate zero(Smi::RawValue(0));
3008 movq(dest, zero); 2717 movq(dest, zero);
3009 } 2718 }
3010 2719
3011
3012 void Assembler::IncrementSmiField(const Address& dest, int64_t increment) { 2720 void Assembler::IncrementSmiField(const Address& dest, int64_t increment) {
3013 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on 2721 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
3014 // the length of this instruction sequence. 2722 // the length of this instruction sequence.
3015 Immediate inc_imm(Smi::RawValue(increment)); 2723 Immediate inc_imm(Smi::RawValue(increment));
3016 addq(dest, inc_imm); 2724 addq(dest, inc_imm);
3017 } 2725 }
3018 2726
3019
3020 void Assembler::DoubleNegate(XmmRegister d) { 2727 void Assembler::DoubleNegate(XmmRegister d) {
3021 // {0x8000000000000000LL, 0x8000000000000000LL} 2728 // {0x8000000000000000LL, 0x8000000000000000LL}
3022 movq(TMP, Address(THR, Thread::double_negate_address_offset())); 2729 movq(TMP, Address(THR, Thread::double_negate_address_offset()));
3023 xorpd(d, Address(TMP, 0)); 2730 xorpd(d, Address(TMP, 0));
3024 } 2731 }
3025 2732
3026
3027 void Assembler::DoubleAbs(XmmRegister reg) { 2733 void Assembler::DoubleAbs(XmmRegister reg) {
3028 // {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL} 2734 // {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}
3029 movq(TMP, Address(THR, Thread::double_abs_address_offset())); 2735 movq(TMP, Address(THR, Thread::double_abs_address_offset()));
3030 andpd(reg, Address(TMP, 0)); 2736 andpd(reg, Address(TMP, 0));
3031 } 2737 }
3032 2738
3033
3034 void Assembler::Stop(const char* message, bool fixed_length_encoding) { 2739 void Assembler::Stop(const char* message, bool fixed_length_encoding) {
3035 int64_t message_address = reinterpret_cast<int64_t>(message); 2740 int64_t message_address = reinterpret_cast<int64_t>(message);
3036 if (FLAG_print_stop_message) { 2741 if (FLAG_print_stop_message) {
3037 pushq(TMP); // Preserve TMP register. 2742 pushq(TMP); // Preserve TMP register.
3038 pushq(RDI); // Preserve RDI register. 2743 pushq(RDI); // Preserve RDI register.
3039 if (fixed_length_encoding) { 2744 if (fixed_length_encoding) {
3040 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2745 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3041 EmitRegisterREX(RDI, REX_W); 2746 EmitRegisterREX(RDI, REX_W);
3042 EmitUint8(0xB8 | (RDI & 7)); 2747 EmitUint8(0xB8 | (RDI & 7));
3043 EmitInt64(message_address); 2748 EmitInt64(message_address);
3044 } else { 2749 } else {
3045 LoadImmediate(RDI, Immediate(message_address)); 2750 LoadImmediate(RDI, Immediate(message_address));
3046 } 2751 }
3047 call(&StubCode::PrintStopMessage_entry()->label()); 2752 call(&StubCode::PrintStopMessage_entry()->label());
3048 popq(RDI); // Restore RDI register. 2753 popq(RDI); // Restore RDI register.
3049 popq(TMP); // Restore TMP register. 2754 popq(TMP); // Restore TMP register.
3050 } else { 2755 } else {
3051 // Emit the lower half and the higher half of the message address as 2756 // Emit the lower half and the higher half of the message address as
3052 // immediate operands in the test rax instructions. 2757 // immediate operands in the test rax instructions.
3053 testl(RAX, Immediate(Utils::Low32Bits(message_address))); 2758 testl(RAX, Immediate(Utils::Low32Bits(message_address)));
3054 testl(RAX, Immediate(Utils::High32Bits(message_address))); 2759 testl(RAX, Immediate(Utils::High32Bits(message_address)));
3055 } 2760 }
3056 // Emit the int3 instruction. 2761 // Emit the int3 instruction.
3057 int3(); // Execution can be resumed with the 'cont' command in gdb. 2762 int3(); // Execution can be resumed with the 'cont' command in gdb.
3058 } 2763 }
3059 2764
3060
3061 void Assembler::Bind(Label* label) { 2765 void Assembler::Bind(Label* label) {
3062 intptr_t bound = buffer_.Size(); 2766 intptr_t bound = buffer_.Size();
3063 ASSERT(!label->IsBound()); // Labels can only be bound once. 2767 ASSERT(!label->IsBound()); // Labels can only be bound once.
3064 while (label->IsLinked()) { 2768 while (label->IsLinked()) {
3065 intptr_t position = label->LinkPosition(); 2769 intptr_t position = label->LinkPosition();
3066 intptr_t next = buffer_.Load<int32_t>(position); 2770 intptr_t next = buffer_.Load<int32_t>(position);
3067 buffer_.Store<int32_t>(position, bound - (position + 4)); 2771 buffer_.Store<int32_t>(position, bound - (position + 4));
3068 label->position_ = next; 2772 label->position_ = next;
3069 } 2773 }
3070 while (label->HasNear()) { 2774 while (label->HasNear()) {
3071 intptr_t position = label->NearPosition(); 2775 intptr_t position = label->NearPosition();
3072 intptr_t offset = bound - (position + 1); 2776 intptr_t offset = bound - (position + 1);
3073 ASSERT(Utils::IsInt(8, offset)); 2777 ASSERT(Utils::IsInt(8, offset));
3074 buffer_.Store<int8_t>(position, offset); 2778 buffer_.Store<int8_t>(position, offset);
3075 } 2779 }
3076 label->BindTo(bound); 2780 label->BindTo(bound);
3077 } 2781 }
3078 2782
3079
3080 void Assembler::EnterFrame(intptr_t frame_size) { 2783 void Assembler::EnterFrame(intptr_t frame_size) {
3081 if (prologue_offset_ == -1) { 2784 if (prologue_offset_ == -1) {
3082 prologue_offset_ = CodeSize(); 2785 prologue_offset_ = CodeSize();
3083 Comment("PrologueOffset = %" Pd "", CodeSize()); 2786 Comment("PrologueOffset = %" Pd "", CodeSize());
3084 } 2787 }
3085 #ifdef DEBUG 2788 #ifdef DEBUG
3086 intptr_t check_offset = CodeSize(); 2789 intptr_t check_offset = CodeSize();
3087 #endif 2790 #endif
3088 pushq(RBP); 2791 pushq(RBP);
3089 movq(RBP, RSP); 2792 movq(RBP, RSP);
3090 #ifdef DEBUG 2793 #ifdef DEBUG
3091 ProloguePattern pp(CodeAddress(check_offset)); 2794 ProloguePattern pp(CodeAddress(check_offset));
3092 ASSERT(pp.IsValid()); 2795 ASSERT(pp.IsValid());
3093 #endif 2796 #endif
3094 if (frame_size != 0) { 2797 if (frame_size != 0) {
3095 Immediate frame_space(frame_size); 2798 Immediate frame_space(frame_size);
3096 subq(RSP, frame_space); 2799 subq(RSP, frame_space);
3097 } 2800 }
3098 } 2801 }
3099 2802
3100
3101 void Assembler::LeaveFrame() { 2803 void Assembler::LeaveFrame() {
3102 movq(RSP, RBP); 2804 movq(RSP, RBP);
3103 popq(RBP); 2805 popq(RBP);
3104 } 2806 }
3105 2807
3106
3107 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { 2808 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
3108 // Reserve space for arguments and align frame before entering 2809 // Reserve space for arguments and align frame before entering
3109 // the C++ world. 2810 // the C++ world.
3110 if (frame_space != 0) { 2811 if (frame_space != 0) {
3111 subq(RSP, Immediate(frame_space)); 2812 subq(RSP, Immediate(frame_space));
3112 } 2813 }
3113 if (OS::ActivationFrameAlignment() > 1) { 2814 if (OS::ActivationFrameAlignment() > 1) {
3114 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 2815 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
3115 } 2816 }
3116 } 2817 }
3117 2818
3118
3119 void Assembler::PushRegisters(intptr_t cpu_register_set, 2819 void Assembler::PushRegisters(intptr_t cpu_register_set,
3120 intptr_t xmm_register_set) { 2820 intptr_t xmm_register_set) {
3121 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set); 2821 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set);
3122 if (xmm_regs_count > 0) { 2822 if (xmm_regs_count > 0) {
3123 AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize)); 2823 AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize));
3124 // Store XMM registers with the lowest register number at the lowest 2824 // Store XMM registers with the lowest register number at the lowest
3125 // address. 2825 // address.
3126 intptr_t offset = 0; 2826 intptr_t offset = 0;
3127 for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) { 2827 for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) {
3128 XmmRegister xmm_reg = static_cast<XmmRegister>(i); 2828 XmmRegister xmm_reg = static_cast<XmmRegister>(i);
3129 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) { 2829 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) {
3130 movups(Address(RSP, offset), xmm_reg); 2830 movups(Address(RSP, offset), xmm_reg);
3131 offset += kFpuRegisterSize; 2831 offset += kFpuRegisterSize;
3132 } 2832 }
3133 } 2833 }
3134 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); 2834 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize));
3135 } 2835 }
3136 2836
3137 // The order in which the registers are pushed must match the order 2837 // The order in which the registers are pushed must match the order
3138 // in which the registers are encoded in the safe point's stack map. 2838 // in which the registers are encoded in the safe point's stack map.
3139 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) { 2839 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) {
3140 Register reg = static_cast<Register>(i); 2840 Register reg = static_cast<Register>(i);
3141 if (RegisterSet::Contains(cpu_register_set, reg)) { 2841 if (RegisterSet::Contains(cpu_register_set, reg)) {
3142 pushq(reg); 2842 pushq(reg);
3143 } 2843 }
3144 } 2844 }
3145 } 2845 }
3146 2846
3147
3148 void Assembler::PopRegisters(intptr_t cpu_register_set, 2847 void Assembler::PopRegisters(intptr_t cpu_register_set,
3149 intptr_t xmm_register_set) { 2848 intptr_t xmm_register_set) {
3150 for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) { 2849 for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
3151 Register reg = static_cast<Register>(i); 2850 Register reg = static_cast<Register>(i);
3152 if (RegisterSet::Contains(cpu_register_set, reg)) { 2851 if (RegisterSet::Contains(cpu_register_set, reg)) {
3153 popq(reg); 2852 popq(reg);
3154 } 2853 }
3155 } 2854 }
3156 2855
3157 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set); 2856 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set);
3158 if (xmm_regs_count > 0) { 2857 if (xmm_regs_count > 0) {
3159 // XMM registers have the lowest register number at the lowest address. 2858 // XMM registers have the lowest register number at the lowest address.
3160 intptr_t offset = 0; 2859 intptr_t offset = 0;
3161 for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) { 2860 for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) {
3162 XmmRegister xmm_reg = static_cast<XmmRegister>(i); 2861 XmmRegister xmm_reg = static_cast<XmmRegister>(i);
3163 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) { 2862 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) {
3164 movups(xmm_reg, Address(RSP, offset)); 2863 movups(xmm_reg, Address(RSP, offset));
3165 offset += kFpuRegisterSize; 2864 offset += kFpuRegisterSize;
3166 } 2865 }
3167 } 2866 }
3168 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); 2867 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize));
3169 AddImmediate(RSP, Immediate(offset)); 2868 AddImmediate(RSP, Immediate(offset));
3170 } 2869 }
3171 } 2870 }
3172 2871
3173
3174 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { 2872 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
3175 Comment("EnterCallRuntimeFrame"); 2873 Comment("EnterCallRuntimeFrame");
3176 EnterStubFrame(); 2874 EnterStubFrame();
3177 2875
3178 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch. 2876 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
3179 PushRegisters(CallingConventions::kVolatileCpuRegisters, 2877 PushRegisters(CallingConventions::kVolatileCpuRegisters,
3180 CallingConventions::kVolatileXmmRegisters); 2878 CallingConventions::kVolatileXmmRegisters);
3181 2879
3182 ReserveAlignedFrameSpace(frame_space); 2880 ReserveAlignedFrameSpace(frame_space);
3183 } 2881 }
3184 2882
3185
3186 void Assembler::LeaveCallRuntimeFrame() { 2883 void Assembler::LeaveCallRuntimeFrame() {
3187 // RSP might have been modified to reserve space for arguments 2884 // RSP might have been modified to reserve space for arguments
3188 // and ensure proper alignment of the stack frame. 2885 // and ensure proper alignment of the stack frame.
3189 // We need to restore it before restoring registers. 2886 // We need to restore it before restoring registers.
3190 const intptr_t kPushedCpuRegistersCount = 2887 const intptr_t kPushedCpuRegistersCount =
3191 RegisterSet::RegisterCount(CallingConventions::kVolatileCpuRegisters); 2888 RegisterSet::RegisterCount(CallingConventions::kVolatileCpuRegisters);
3192 const intptr_t kPushedXmmRegistersCount = 2889 const intptr_t kPushedXmmRegistersCount =
3193 RegisterSet::RegisterCount(CallingConventions::kVolatileXmmRegisters); 2890 RegisterSet::RegisterCount(CallingConventions::kVolatileXmmRegisters);
3194 const intptr_t kPushedRegistersSize = 2891 const intptr_t kPushedRegistersSize =
3195 kPushedCpuRegistersCount * kWordSize + 2892 kPushedCpuRegistersCount * kWordSize +
3196 kPushedXmmRegistersCount * kFpuRegisterSize + 2893 kPushedXmmRegistersCount * kFpuRegisterSize +
3197 2 * kWordSize; // PP, pc marker from EnterStubFrame 2894 2 * kWordSize; // PP, pc marker from EnterStubFrame
3198 leaq(RSP, Address(RBP, -kPushedRegistersSize)); 2895 leaq(RSP, Address(RBP, -kPushedRegistersSize));
3199 2896
3200 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch. 2897 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
3201 PopRegisters(CallingConventions::kVolatileCpuRegisters, 2898 PopRegisters(CallingConventions::kVolatileCpuRegisters,
3202 CallingConventions::kVolatileXmmRegisters); 2899 CallingConventions::kVolatileXmmRegisters);
3203 2900
3204 LeaveStubFrame(); 2901 LeaveStubFrame();
3205 } 2902 }
3206 2903
3207
3208 void Assembler::CallCFunction(Register reg) { 2904 void Assembler::CallCFunction(Register reg) {
3209 // Reserve shadow space for outgoing arguments. 2905 // Reserve shadow space for outgoing arguments.
3210 if (CallingConventions::kShadowSpaceBytes != 0) { 2906 if (CallingConventions::kShadowSpaceBytes != 0) {
3211 subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes)); 2907 subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
3212 } 2908 }
3213 call(reg); 2909 call(reg);
3214 } 2910 }
3215 2911
3216
3217 void Assembler::CallRuntime(const RuntimeEntry& entry, 2912 void Assembler::CallRuntime(const RuntimeEntry& entry,
3218 intptr_t argument_count) { 2913 intptr_t argument_count) {
3219 entry.Call(this, argument_count); 2914 entry.Call(this, argument_count);
3220 } 2915 }
3221 2916
3222
3223 void Assembler::RestoreCodePointer() { 2917 void Assembler::RestoreCodePointer() {
3224 movq(CODE_REG, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); 2918 movq(CODE_REG, Address(RBP, kPcMarkerSlotFromFp * kWordSize));
3225 } 2919 }
3226 2920
3227
3228 void Assembler::LoadPoolPointer(Register pp) { 2921 void Assembler::LoadPoolPointer(Register pp) {
3229 // Load new pool pointer. 2922 // Load new pool pointer.
3230 CheckCodePointer(); 2923 CheckCodePointer();
3231 movq(pp, FieldAddress(CODE_REG, Code::object_pool_offset())); 2924 movq(pp, FieldAddress(CODE_REG, Code::object_pool_offset()));
3232 set_constant_pool_allowed(pp == PP); 2925 set_constant_pool_allowed(pp == PP);
3233 } 2926 }
3234 2927
3235
3236 void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) { 2928 void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) {
3237 ASSERT(!constant_pool_allowed()); 2929 ASSERT(!constant_pool_allowed());
3238 EnterFrame(0); 2930 EnterFrame(0);
3239 pushq(CODE_REG); 2931 pushq(CODE_REG);
3240 pushq(PP); 2932 pushq(PP);
3241 if (new_pp == kNoRegister) { 2933 if (new_pp == kNoRegister) {
3242 LoadPoolPointer(PP); 2934 LoadPoolPointer(PP);
3243 } else { 2935 } else {
3244 movq(PP, new_pp); 2936 movq(PP, new_pp);
3245 } 2937 }
3246 set_constant_pool_allowed(true); 2938 set_constant_pool_allowed(true);
3247 if (frame_size != 0) { 2939 if (frame_size != 0) {
3248 subq(RSP, Immediate(frame_size)); 2940 subq(RSP, Immediate(frame_size));
3249 } 2941 }
3250 } 2942 }
3251 2943
3252
3253 void Assembler::LeaveDartFrame(RestorePP restore_pp) { 2944 void Assembler::LeaveDartFrame(RestorePP restore_pp) {
3254 // Restore caller's PP register that was pushed in EnterDartFrame. 2945 // Restore caller's PP register that was pushed in EnterDartFrame.
3255 if (restore_pp == kRestoreCallerPP) { 2946 if (restore_pp == kRestoreCallerPP) {
3256 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); 2947 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize)));
3257 set_constant_pool_allowed(false); 2948 set_constant_pool_allowed(false);
3258 } 2949 }
3259 LeaveFrame(); 2950 LeaveFrame();
3260 } 2951 }
3261 2952
3262
3263 void Assembler::CheckCodePointer() { 2953 void Assembler::CheckCodePointer() {
3264 #ifdef DEBUG 2954 #ifdef DEBUG
3265 if (!FLAG_check_code_pointer) { 2955 if (!FLAG_check_code_pointer) {
3266 return; 2956 return;
3267 } 2957 }
3268 Comment("CheckCodePointer"); 2958 Comment("CheckCodePointer");
3269 Label cid_ok, instructions_ok; 2959 Label cid_ok, instructions_ok;
3270 pushq(RAX); 2960 pushq(RAX);
3271 LoadClassId(RAX, CODE_REG); 2961 LoadClassId(RAX, CODE_REG);
3272 cmpq(RAX, Immediate(kCodeCid)); 2962 cmpq(RAX, Immediate(kCodeCid));
(...skipping 10 matching lines...) Expand all
3283 ASSERT(CodeSize() == (header_to_rip_offset - header_to_entry_offset)); 2973 ASSERT(CodeSize() == (header_to_rip_offset - header_to_entry_offset));
3284 } 2974 }
3285 cmpq(RAX, FieldAddress(CODE_REG, Code::saved_instructions_offset())); 2975 cmpq(RAX, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
3286 j(EQUAL, &instructions_ok); 2976 j(EQUAL, &instructions_ok);
3287 int3(); 2977 int3();
3288 Bind(&instructions_ok); 2978 Bind(&instructions_ok);
3289 popq(RAX); 2979 popq(RAX);
3290 #endif 2980 #endif
3291 } 2981 }
3292 2982
3293
3294 // On entry to a function compiled for OSR, the caller's frame pointer, the 2983 // On entry to a function compiled for OSR, the caller's frame pointer, the
3295 // stack locals, and any copied parameters are already in place. The frame 2984 // stack locals, and any copied parameters are already in place. The frame
3296 // pointer is already set up. The PC marker is not correct for the 2985 // pointer is already set up. The PC marker is not correct for the
3297 // optimized function and there may be extra space for spill slots to 2986 // optimized function and there may be extra space for spill slots to
3298 // allocate. 2987 // allocate.
3299 void Assembler::EnterOsrFrame(intptr_t extra_size) { 2988 void Assembler::EnterOsrFrame(intptr_t extra_size) {
3300 ASSERT(!constant_pool_allowed()); 2989 ASSERT(!constant_pool_allowed());
3301 if (prologue_offset_ == -1) { 2990 if (prologue_offset_ == -1) {
3302 Comment("PrologueOffset = %" Pd "", CodeSize()); 2991 Comment("PrologueOffset = %" Pd "", CodeSize());
3303 prologue_offset_ = CodeSize(); 2992 prologue_offset_ = CodeSize();
3304 } 2993 }
3305 RestoreCodePointer(); 2994 RestoreCodePointer();
3306 LoadPoolPointer(); 2995 LoadPoolPointer();
3307 2996
3308 if (extra_size != 0) { 2997 if (extra_size != 0) {
3309 subq(RSP, Immediate(extra_size)); 2998 subq(RSP, Immediate(extra_size));
3310 } 2999 }
3311 } 3000 }
3312 3001
3313
3314 void Assembler::EnterStubFrame() { 3002 void Assembler::EnterStubFrame() {
3315 EnterDartFrame(0, kNoRegister); 3003 EnterDartFrame(0, kNoRegister);
3316 } 3004 }
3317 3005
3318
3319 void Assembler::LeaveStubFrame() { 3006 void Assembler::LeaveStubFrame() {
3320 LeaveDartFrame(); 3007 LeaveDartFrame();
3321 } 3008 }
3322 3009
3323
3324 // RDI receiver, RBX guarded cid as Smi 3010 // RDI receiver, RBX guarded cid as Smi
3325 void Assembler::MonomorphicCheckedEntry() { 3011 void Assembler::MonomorphicCheckedEntry() {
3326 ASSERT(has_single_entry_point_); 3012 ASSERT(has_single_entry_point_);
3327 has_single_entry_point_ = false; 3013 has_single_entry_point_ = false;
3328 Label immediate, have_cid, miss; 3014 Label immediate, have_cid, miss;
3329 Bind(&miss); 3015 Bind(&miss);
3330 jmp(Address(THR, Thread::monomorphic_miss_entry_offset())); 3016 jmp(Address(THR, Thread::monomorphic_miss_entry_offset()));
3331 3017
3332 Bind(&immediate); 3018 Bind(&immediate);
3333 movq(R10, Immediate(kSmiCid)); 3019 movq(R10, Immediate(kSmiCid));
3334 jmp(&have_cid, kNearJump); 3020 jmp(&have_cid, kNearJump);
3335 3021
3336 Comment("MonomorphicCheckedEntry"); 3022 Comment("MonomorphicCheckedEntry");
3337 ASSERT(CodeSize() == Instructions::kCheckedEntryOffset); 3023 ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
3338 SmiUntag(RBX); 3024 SmiUntag(RBX);
3339 testq(RDI, Immediate(kSmiTagMask)); 3025 testq(RDI, Immediate(kSmiTagMask));
3340 j(ZERO, &immediate, kNearJump); 3026 j(ZERO, &immediate, kNearJump);
3341 3027
3342 LoadClassId(R10, RDI); 3028 LoadClassId(R10, RDI);
3343 3029
3344 Bind(&have_cid); 3030 Bind(&have_cid);
3345 cmpq(R10, RBX); 3031 cmpq(R10, RBX);
3346 j(NOT_EQUAL, &miss, Assembler::kNearJump); 3032 j(NOT_EQUAL, &miss, Assembler::kNearJump);
3347 3033
3348 // Fall through to unchecked entry. 3034 // Fall through to unchecked entry.
3349 ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset); 3035 ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset);
3350 ASSERT((CodeSize() & kSmiTagMask) == kSmiTag); 3036 ASSERT((CodeSize() & kSmiTagMask) == kSmiTag);
3351 } 3037 }
3352 3038
3353
3354 #ifndef PRODUCT 3039 #ifndef PRODUCT
3355 void Assembler::MaybeTraceAllocation(intptr_t cid, 3040 void Assembler::MaybeTraceAllocation(intptr_t cid,
3356 Label* trace, 3041 Label* trace,
3357 bool near_jump) { 3042 bool near_jump) {
3358 ASSERT(cid > 0); 3043 ASSERT(cid > 0);
3359 intptr_t state_offset = ClassTable::StateOffsetFor(cid); 3044 intptr_t state_offset = ClassTable::StateOffsetFor(cid);
3360 Register temp_reg = TMP; 3045 Register temp_reg = TMP;
3361 LoadIsolate(temp_reg); 3046 LoadIsolate(temp_reg);
3362 intptr_t table_offset = 3047 intptr_t table_offset =
3363 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); 3048 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
3364 movq(temp_reg, Address(temp_reg, table_offset)); 3049 movq(temp_reg, Address(temp_reg, table_offset));
3365 testb(Address(temp_reg, state_offset), 3050 testb(Address(temp_reg, state_offset),
3366 Immediate(ClassHeapStats::TraceAllocationMask())); 3051 Immediate(ClassHeapStats::TraceAllocationMask()));
3367 // We are tracing for this class, jump to the trace label which will use 3052 // We are tracing for this class, jump to the trace label which will use
3368 // the allocation stub. 3053 // the allocation stub.
3369 j(NOT_ZERO, trace, near_jump); 3054 j(NOT_ZERO, trace, near_jump);
3370 } 3055 }
3371 3056
3372
3373 void Assembler::UpdateAllocationStats(intptr_t cid, Heap::Space space) { 3057 void Assembler::UpdateAllocationStats(intptr_t cid, Heap::Space space) {
3374 ASSERT(cid > 0); 3058 ASSERT(cid > 0);
3375 intptr_t counter_offset = 3059 intptr_t counter_offset =
3376 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); 3060 ClassTable::CounterOffsetFor(cid, space == Heap::kNew);
3377 Register temp_reg = TMP; 3061 Register temp_reg = TMP;
3378 LoadIsolate(temp_reg); 3062 LoadIsolate(temp_reg);
3379 intptr_t table_offset = 3063 intptr_t table_offset =
3380 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); 3064 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
3381 movq(temp_reg, Address(temp_reg, table_offset)); 3065 movq(temp_reg, Address(temp_reg, table_offset));
3382 incq(Address(temp_reg, counter_offset)); 3066 incq(Address(temp_reg, counter_offset));
3383 } 3067 }
3384 3068
3385
3386 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, 3069 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
3387 Register size_reg, 3070 Register size_reg,
3388 Heap::Space space) { 3071 Heap::Space space) {
3389 ASSERT(cid > 0); 3072 ASSERT(cid > 0);
3390 ASSERT(cid < kNumPredefinedCids); 3073 ASSERT(cid < kNumPredefinedCids);
3391 UpdateAllocationStats(cid, space); 3074 UpdateAllocationStats(cid, space);
3392 Register temp_reg = TMP; 3075 Register temp_reg = TMP;
3393 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); 3076 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
3394 addq(Address(temp_reg, size_offset), size_reg); 3077 addq(Address(temp_reg, size_offset), size_reg);
3395 } 3078 }
3396 3079
3397
3398 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, 3080 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
3399 intptr_t size_in_bytes, 3081 intptr_t size_in_bytes,
3400 Heap::Space space) { 3082 Heap::Space space) {
3401 ASSERT(cid > 0); 3083 ASSERT(cid > 0);
3402 ASSERT(cid < kNumPredefinedCids); 3084 ASSERT(cid < kNumPredefinedCids);
3403 UpdateAllocationStats(cid, space); 3085 UpdateAllocationStats(cid, space);
3404 Register temp_reg = TMP; 3086 Register temp_reg = TMP;
3405 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); 3087 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
3406 addq(Address(temp_reg, size_offset), Immediate(size_in_bytes)); 3088 addq(Address(temp_reg, size_offset), Immediate(size_in_bytes));
3407 } 3089 }
3408 #endif // !PRODUCT 3090 #endif // !PRODUCT
3409 3091
3410
3411 void Assembler::TryAllocate(const Class& cls, 3092 void Assembler::TryAllocate(const Class& cls,
3412 Label* failure, 3093 Label* failure,
3413 bool near_jump, 3094 bool near_jump,
3414 Register instance_reg, 3095 Register instance_reg,
3415 Register temp) { 3096 Register temp) {
3416 ASSERT(failure != NULL); 3097 ASSERT(failure != NULL);
3417 if (FLAG_inline_alloc) { 3098 if (FLAG_inline_alloc) {
3418 // If this allocation is traced, program will jump to failure path 3099 // If this allocation is traced, program will jump to failure path
3419 // (i.e. the allocation stub) which will allocate the object and trace the 3100 // (i.e. the allocation stub) which will allocate the object and trace the
3420 // allocation call site. 3101 // allocation call site.
(...skipping 18 matching lines...) Expand all
3439 tags = RawObject::ClassIdTag::update(cls.id(), tags); 3120 tags = RawObject::ClassIdTag::update(cls.id(), tags);
3440 // Extends the 32 bit tags with zeros, which is the uninitialized 3121 // Extends the 32 bit tags with zeros, which is the uninitialized
3441 // hash code. 3122 // hash code.
3442 MoveImmediate(FieldAddress(instance_reg, Object::tags_offset()), 3123 MoveImmediate(FieldAddress(instance_reg, Object::tags_offset()),
3443 Immediate(tags)); 3124 Immediate(tags));
3444 } else { 3125 } else {
3445 jmp(failure); 3126 jmp(failure);
3446 } 3127 }
3447 } 3128 }
3448 3129
3449
3450 void Assembler::TryAllocateArray(intptr_t cid, 3130 void Assembler::TryAllocateArray(intptr_t cid,
3451 intptr_t instance_size, 3131 intptr_t instance_size,
3452 Label* failure, 3132 Label* failure,
3453 bool near_jump, 3133 bool near_jump,
3454 Register instance, 3134 Register instance,
3455 Register end_address, 3135 Register end_address,
3456 Register temp) { 3136 Register temp) {
3457 ASSERT(failure != NULL); 3137 ASSERT(failure != NULL);
3458 if (FLAG_inline_alloc) { 3138 if (FLAG_inline_alloc) {
3459 // If this allocation is traced, program will jump to failure path 3139 // If this allocation is traced, program will jump to failure path
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3504 while (bytes_needed > MAX_NOP_SIZE) { 3184 while (bytes_needed > MAX_NOP_SIZE) {
3505 nop(MAX_NOP_SIZE); 3185 nop(MAX_NOP_SIZE);
3506 bytes_needed -= MAX_NOP_SIZE; 3186 bytes_needed -= MAX_NOP_SIZE;
3507 } 3187 }
3508 if (bytes_needed) { 3188 if (bytes_needed) {
3509 nop(bytes_needed); 3189 nop(bytes_needed);
3510 } 3190 }
3511 ASSERT(((offset + buffer_.GetPosition()) & (alignment - 1)) == 0); 3191 ASSERT(((offset + buffer_.GetPosition()) & (alignment - 1)) == 0);
3512 } 3192 }
3513 3193
3514
3515 void Assembler::EmitOperand(int rm, const Operand& operand) { 3194 void Assembler::EmitOperand(int rm, const Operand& operand) {
3516 ASSERT(rm >= 0 && rm < 8); 3195 ASSERT(rm >= 0 && rm < 8);
3517 const intptr_t length = operand.length_; 3196 const intptr_t length = operand.length_;
3518 ASSERT(length > 0); 3197 ASSERT(length > 0);
3519 // Emit the ModRM byte updated with the given RM value. 3198 // Emit the ModRM byte updated with the given RM value.
3520 ASSERT((operand.encoding_[0] & 0x38) == 0); 3199 ASSERT((operand.encoding_[0] & 0x38) == 0);
3521 EmitUint8(operand.encoding_[0] + (rm << 3)); 3200 EmitUint8(operand.encoding_[0] + (rm << 3));
3522 // Emit the rest of the encoded operand. 3201 // Emit the rest of the encoded operand.
3523 for (intptr_t i = 1; i < length; i++) { 3202 for (intptr_t i = 1; i < length; i++) {
3524 EmitUint8(operand.encoding_[i]); 3203 EmitUint8(operand.encoding_[i]);
3525 } 3204 }
3526 } 3205 }
3527 3206
3528
3529 void Assembler::EmitXmmRegisterOperand(int rm, XmmRegister xmm_reg) { 3207 void Assembler::EmitXmmRegisterOperand(int rm, XmmRegister xmm_reg) {
3530 Operand operand; 3208 Operand operand;
3531 operand.SetModRM(3, static_cast<Register>(xmm_reg)); 3209 operand.SetModRM(3, static_cast<Register>(xmm_reg));
3532 EmitOperand(rm, operand); 3210 EmitOperand(rm, operand);
3533 } 3211 }
3534 3212
3535
3536 void Assembler::EmitImmediate(const Immediate& imm) { 3213 void Assembler::EmitImmediate(const Immediate& imm) {
3537 if (imm.is_int32()) { 3214 if (imm.is_int32()) {
3538 EmitInt32(static_cast<int32_t>(imm.value())); 3215 EmitInt32(static_cast<int32_t>(imm.value()));
3539 } else { 3216 } else {
3540 EmitInt64(imm.value()); 3217 EmitInt64(imm.value());
3541 } 3218 }
3542 } 3219 }
3543 3220
3544
3545 void Assembler::EmitComplex(int rm, 3221 void Assembler::EmitComplex(int rm,
3546 const Operand& operand, 3222 const Operand& operand,
3547 const Immediate& immediate) { 3223 const Immediate& immediate) {
3548 ASSERT(rm >= 0 && rm < 8); 3224 ASSERT(rm >= 0 && rm < 8);
3549 ASSERT(immediate.is_int32()); 3225 ASSERT(immediate.is_int32());
3550 if (immediate.is_int8()) { 3226 if (immediate.is_int8()) {
3551 // Use sign-extended 8-bit immediate. 3227 // Use sign-extended 8-bit immediate.
3552 EmitUint8(0x83); 3228 EmitUint8(0x83);
3553 EmitOperand(rm, operand); 3229 EmitOperand(rm, operand);
3554 EmitUint8(immediate.value() & 0xFF); 3230 EmitUint8(immediate.value() & 0xFF);
3555 } else if (operand.IsRegister(RAX)) { 3231 } else if (operand.IsRegister(RAX)) {
3556 // Use short form if the destination is rax. 3232 // Use short form if the destination is rax.
3557 EmitUint8(0x05 + (rm << 3)); 3233 EmitUint8(0x05 + (rm << 3));
3558 EmitImmediate(immediate); 3234 EmitImmediate(immediate);
3559 } else { 3235 } else {
3560 EmitUint8(0x81); 3236 EmitUint8(0x81);
3561 EmitOperand(rm, operand); 3237 EmitOperand(rm, operand);
3562 EmitImmediate(immediate); 3238 EmitImmediate(immediate);
3563 } 3239 }
3564 } 3240 }
3565 3241
3566
3567 void Assembler::EmitLabel(Label* label, intptr_t instruction_size) { 3242 void Assembler::EmitLabel(Label* label, intptr_t instruction_size) {
3568 if (label->IsBound()) { 3243 if (label->IsBound()) {
3569 intptr_t offset = label->Position() - buffer_.Size(); 3244 intptr_t offset = label->Position() - buffer_.Size();
3570 ASSERT(offset <= 0); 3245 ASSERT(offset <= 0);
3571 EmitInt32(offset - instruction_size); 3246 EmitInt32(offset - instruction_size);
3572 } else { 3247 } else {
3573 EmitLabelLink(label); 3248 EmitLabelLink(label);
3574 } 3249 }
3575 } 3250 }
3576 3251
3577
3578 void Assembler::EmitLabelLink(Label* label) { 3252 void Assembler::EmitLabelLink(Label* label) {
3579 ASSERT(!label->IsBound()); 3253 ASSERT(!label->IsBound());
3580 intptr_t position = buffer_.Size(); 3254 intptr_t position = buffer_.Size();
3581 EmitInt32(label->position_); 3255 EmitInt32(label->position_);
3582 label->LinkTo(position); 3256 label->LinkTo(position);
3583 } 3257 }
3584 3258
3585
3586 void Assembler::EmitNearLabelLink(Label* label) { 3259 void Assembler::EmitNearLabelLink(Label* label) {
3587 ASSERT(!label->IsBound()); 3260 ASSERT(!label->IsBound());
3588 intptr_t position = buffer_.Size(); 3261 intptr_t position = buffer_.Size();
3589 EmitUint8(0); 3262 EmitUint8(0);
3590 label->NearLinkTo(position); 3263 label->NearLinkTo(position);
3591 } 3264 }
3592 3265
3593
3594 void Assembler::EmitGenericShift(bool wide, 3266 void Assembler::EmitGenericShift(bool wide,
3595 int rm, 3267 int rm,
3596 Register reg, 3268 Register reg,
3597 const Immediate& imm) { 3269 const Immediate& imm) {
3598 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 3270 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3599 ASSERT(imm.is_int8()); 3271 ASSERT(imm.is_int8());
3600 if (wide) { 3272 if (wide) {
3601 EmitRegisterREX(reg, REX_W); 3273 EmitRegisterREX(reg, REX_W);
3602 } else { 3274 } else {
3603 EmitRegisterREX(reg, REX_NONE); 3275 EmitRegisterREX(reg, REX_NONE);
3604 } 3276 }
3605 if (imm.value() == 1) { 3277 if (imm.value() == 1) {
3606 EmitUint8(0xD1); 3278 EmitUint8(0xD1);
3607 EmitOperand(rm, Operand(reg)); 3279 EmitOperand(rm, Operand(reg));
3608 } else { 3280 } else {
3609 EmitUint8(0xC1); 3281 EmitUint8(0xC1);
3610 EmitOperand(rm, Operand(reg)); 3282 EmitOperand(rm, Operand(reg));
3611 EmitUint8(imm.value() & 0xFF); 3283 EmitUint8(imm.value() & 0xFF);
3612 } 3284 }
3613 } 3285 }
3614 3286
3615
3616 void Assembler::EmitGenericShift(bool wide, 3287 void Assembler::EmitGenericShift(bool wide,
3617 int rm, 3288 int rm,
3618 Register operand, 3289 Register operand,
3619 Register shifter) { 3290 Register shifter) {
3620 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 3291 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3621 ASSERT(shifter == RCX); 3292 ASSERT(shifter == RCX);
3622 if (wide) { 3293 if (wide) {
3623 EmitRegisterREX(operand, REX_W); 3294 EmitRegisterREX(operand, REX_W);
3624 } else { 3295 } else {
3625 EmitRegisterREX(operand, REX_NONE); 3296 EmitRegisterREX(operand, REX_NONE);
3626 } 3297 }
3627 EmitUint8(0xD3); 3298 EmitUint8(0xD3);
3628 EmitOperand(rm, Operand(operand)); 3299 EmitOperand(rm, Operand(operand));
3629 } 3300 }
3630 3301
3631
3632 void Assembler::LoadClassId(Register result, Register object) { 3302 void Assembler::LoadClassId(Register result, Register object) {
3633 ASSERT(RawObject::kClassIdTagPos == 16); 3303 ASSERT(RawObject::kClassIdTagPos == 16);
3634 ASSERT(RawObject::kClassIdTagSize == 16); 3304 ASSERT(RawObject::kClassIdTagSize == 16);
3635 ASSERT(sizeof(classid_t) == sizeof(uint16_t)); 3305 ASSERT(sizeof(classid_t) == sizeof(uint16_t));
3636 const intptr_t class_id_offset = 3306 const intptr_t class_id_offset =
3637 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte; 3307 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
3638 movzxw(result, FieldAddress(object, class_id_offset)); 3308 movzxw(result, FieldAddress(object, class_id_offset));
3639 } 3309 }
3640 3310
3641
3642 void Assembler::LoadClassById(Register result, Register class_id) { 3311 void Assembler::LoadClassById(Register result, Register class_id) {
3643 ASSERT(result != class_id); 3312 ASSERT(result != class_id);
3644 LoadIsolate(result); 3313 LoadIsolate(result);
3645 const intptr_t offset = 3314 const intptr_t offset =
3646 Isolate::class_table_offset() + ClassTable::table_offset(); 3315 Isolate::class_table_offset() + ClassTable::table_offset();
3647 movq(result, Address(result, offset)); 3316 movq(result, Address(result, offset));
3648 movq(result, Address(result, class_id, TIMES_8, 0)); 3317 movq(result, Address(result, class_id, TIMES_8, 0));
3649 } 3318 }
3650 3319
3651
3652 void Assembler::LoadClass(Register result, Register object) { 3320 void Assembler::LoadClass(Register result, Register object) {
3653 LoadClassId(TMP, object); 3321 LoadClassId(TMP, object);
3654 LoadClassById(result, TMP); 3322 LoadClassById(result, TMP);
3655 } 3323 }
3656 3324
3657
3658 void Assembler::CompareClassId(Register object, intptr_t class_id) { 3325 void Assembler::CompareClassId(Register object, intptr_t class_id) {
3659 LoadClassId(TMP, object); 3326 LoadClassId(TMP, object);
3660 cmpl(TMP, Immediate(class_id)); 3327 cmpl(TMP, Immediate(class_id));
3661 } 3328 }
3662 3329
3663
3664 void Assembler::SmiUntagOrCheckClass(Register object, 3330 void Assembler::SmiUntagOrCheckClass(Register object,
3665 intptr_t class_id, 3331 intptr_t class_id,
3666 Label* is_smi) { 3332 Label* is_smi) {
3667 ASSERT(kSmiTagShift == 1); 3333 ASSERT(kSmiTagShift == 1);
3668 ASSERT(RawObject::kClassIdTagPos == 16); 3334 ASSERT(RawObject::kClassIdTagPos == 16);
3669 ASSERT(RawObject::kClassIdTagSize == 16); 3335 ASSERT(RawObject::kClassIdTagSize == 16);
3670 ASSERT(sizeof(classid_t) == sizeof(uint16_t)); 3336 ASSERT(sizeof(classid_t) == sizeof(uint16_t));
3671 const intptr_t class_id_offset = 3337 const intptr_t class_id_offset =
3672 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte; 3338 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
3673 3339
3674 // Untag optimistically. Tag bit is shifted into the CARRY. 3340 // Untag optimistically. Tag bit is shifted into the CARRY.
3675 SmiUntag(object); 3341 SmiUntag(object);
3676 j(NOT_CARRY, is_smi, kNearJump); 3342 j(NOT_CARRY, is_smi, kNearJump);
3677 // Load cid: can't use LoadClassId, object is untagged. Use TIMES_2 scale 3343 // Load cid: can't use LoadClassId, object is untagged. Use TIMES_2 scale
3678 // factor in the addressing mode to compensate for this. 3344 // factor in the addressing mode to compensate for this.
3679 movzxw(TMP, Address(object, TIMES_2, class_id_offset)); 3345 movzxw(TMP, Address(object, TIMES_2, class_id_offset));
3680 cmpl(TMP, Immediate(class_id)); 3346 cmpl(TMP, Immediate(class_id));
3681 } 3347 }
3682 3348
3683
3684 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) { 3349 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) {
3685 Label smi; 3350 Label smi;
3686 3351
3687 if (result == object) { 3352 if (result == object) {
3688 Label join; 3353 Label join;
3689 3354
3690 testq(object, Immediate(kSmiTagMask)); 3355 testq(object, Immediate(kSmiTagMask));
3691 j(EQUAL, &smi, Assembler::kNearJump); 3356 j(EQUAL, &smi, Assembler::kNearJump);
3692 LoadClassId(result, object); 3357 LoadClassId(result, object);
3693 jmp(&join, Assembler::kNearJump); 3358 jmp(&join, Assembler::kNearJump);
3694 3359
3695 Bind(&smi); 3360 Bind(&smi);
3696 movq(result, Immediate(kSmiCid)); 3361 movq(result, Immediate(kSmiCid));
3697 3362
3698 Bind(&join); 3363 Bind(&join);
3699 } else { 3364 } else {
3700 testq(object, Immediate(kSmiTagMask)); 3365 testq(object, Immediate(kSmiTagMask));
3701 movq(result, Immediate(kSmiCid)); 3366 movq(result, Immediate(kSmiCid));
3702 j(EQUAL, &smi, Assembler::kNearJump); 3367 j(EQUAL, &smi, Assembler::kNearJump);
3703 LoadClassId(result, object); 3368 LoadClassId(result, object);
3704 3369
3705 Bind(&smi); 3370 Bind(&smi);
3706 } 3371 }
3707 } 3372 }
3708 3373
3709
3710 void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) { 3374 void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) {
3711 Label smi; 3375 Label smi;
3712 3376
3713 if (result == object) { 3377 if (result == object) {
3714 Label join; 3378 Label join;
3715 3379
3716 testq(object, Immediate(kSmiTagMask)); 3380 testq(object, Immediate(kSmiTagMask));
3717 j(EQUAL, &smi, Assembler::kNearJump); 3381 j(EQUAL, &smi, Assembler::kNearJump);
3718 LoadClassId(result, object); 3382 LoadClassId(result, object);
3719 SmiTag(result); 3383 SmiTag(result);
3720 jmp(&join, Assembler::kNearJump); 3384 jmp(&join, Assembler::kNearJump);
3721 3385
3722 Bind(&smi); 3386 Bind(&smi);
3723 movq(result, Immediate(Smi::RawValue(kSmiCid))); 3387 movq(result, Immediate(Smi::RawValue(kSmiCid)));
3724 3388
3725 Bind(&join); 3389 Bind(&join);
3726 } else { 3390 } else {
3727 testq(object, Immediate(kSmiTagMask)); 3391 testq(object, Immediate(kSmiTagMask));
3728 movq(result, Immediate(kSmiCid)); 3392 movq(result, Immediate(kSmiCid));
3729 j(EQUAL, &smi, Assembler::kNearJump); 3393 j(EQUAL, &smi, Assembler::kNearJump);
3730 LoadClassId(result, object); 3394 LoadClassId(result, object);
3731 3395
3732 Bind(&smi); 3396 Bind(&smi);
3733 SmiTag(result); 3397 SmiTag(result);
3734 } 3398 }
3735 } 3399 }
3736 3400
3737
3738 Address Assembler::ElementAddressForIntIndex(bool is_external, 3401 Address Assembler::ElementAddressForIntIndex(bool is_external,
3739 intptr_t cid, 3402 intptr_t cid,
3740 intptr_t index_scale, 3403 intptr_t index_scale,
3741 Register array, 3404 Register array,
3742 intptr_t index) { 3405 intptr_t index) {
3743 if (is_external) { 3406 if (is_external) {
3744 return Address(array, index * index_scale); 3407 return Address(array, index * index_scale);
3745 } else { 3408 } else {
3746 const int64_t disp = static_cast<int64_t>(index) * index_scale + 3409 const int64_t disp = static_cast<int64_t>(index) * index_scale +
3747 Instance::DataOffsetFor(cid); 3410 Instance::DataOffsetFor(cid);
3748 ASSERT(Utils::IsInt(32, disp)); 3411 ASSERT(Utils::IsInt(32, disp));
3749 return FieldAddress(array, static_cast<int32_t>(disp)); 3412 return FieldAddress(array, static_cast<int32_t>(disp));
3750 } 3413 }
3751 } 3414 }
3752 3415
3753
3754 static ScaleFactor ToScaleFactor(intptr_t index_scale) { 3416 static ScaleFactor ToScaleFactor(intptr_t index_scale) {
3755 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with 3417 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with
3756 // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is 3418 // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is
3757 // expected to be untagged before accessing. 3419 // expected to be untagged before accessing.
3758 ASSERT(kSmiTagShift == 1); 3420 ASSERT(kSmiTagShift == 1);
3759 switch (index_scale) { 3421 switch (index_scale) {
3760 case 1: 3422 case 1:
3761 return TIMES_1; 3423 return TIMES_1;
3762 case 2: 3424 case 2:
3763 return TIMES_1; 3425 return TIMES_1;
3764 case 4: 3426 case 4:
3765 return TIMES_2; 3427 return TIMES_2;
3766 case 8: 3428 case 8:
3767 return TIMES_4; 3429 return TIMES_4;
3768 case 16: 3430 case 16:
3769 return TIMES_8; 3431 return TIMES_8;
3770 default: 3432 default:
3771 UNREACHABLE(); 3433 UNREACHABLE();
3772 return TIMES_1; 3434 return TIMES_1;
3773 } 3435 }
3774 } 3436 }
3775 3437
3776
3777 Address Assembler::ElementAddressForRegIndex(bool is_external, 3438 Address Assembler::ElementAddressForRegIndex(bool is_external,
3778 intptr_t cid, 3439 intptr_t cid,
3779 intptr_t index_scale, 3440 intptr_t index_scale,
3780 Register array, 3441 Register array,
3781 Register index) { 3442 Register index) {
3782 if (is_external) { 3443 if (is_external) {
3783 return Address(array, index, ToScaleFactor(index_scale), 0); 3444 return Address(array, index, ToScaleFactor(index_scale), 0);
3784 } else { 3445 } else {
3785 return FieldAddress(array, index, ToScaleFactor(index_scale), 3446 return FieldAddress(array, index, ToScaleFactor(index_scale),
3786 Instance::DataOffsetFor(cid)); 3447 Instance::DataOffsetFor(cid));
3787 } 3448 }
3788 } 3449 }
3789 3450
3790
3791 static const char* cpu_reg_names[kNumberOfCpuRegisters] = { 3451 static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
3792 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", 3452 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
3793 "r8", "r9", "r10", "r11", "r12", "r13", "thr", "pp"}; 3453 "r8", "r9", "r10", "r11", "r12", "r13", "thr", "pp"};
3794 3454
3795
3796 const char* Assembler::RegisterName(Register reg) { 3455 const char* Assembler::RegisterName(Register reg) {
3797 ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters)); 3456 ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
3798 return cpu_reg_names[reg]; 3457 return cpu_reg_names[reg];
3799 } 3458 }
3800 3459
3801
3802 static const char* xmm_reg_names[kNumberOfXmmRegisters] = { 3460 static const char* xmm_reg_names[kNumberOfXmmRegisters] = {
3803 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 3461 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
3804 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"}; 3462 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"};
3805 3463
3806
3807 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3464 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3808 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3465 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
3809 return xmm_reg_names[reg]; 3466 return xmm_reg_names[reg];
3810 } 3467 }
3811 3468
3812 } // namespace dart 3469 } // namespace dart
3813 3470
3814 #endif // defined TARGET_ARCH_X64 3471 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698