OLD | NEW |
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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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/memory_region.h" | 12 #include "vm/memory_region.h" |
13 #include "vm/runtime_entry.h" | 13 #include "vm/runtime_entry.h" |
14 #include "vm/stack_frame.h" | 14 #include "vm/stack_frame.h" |
15 #include "vm/stub_code.h" | 15 #include "vm/stub_code.h" |
16 | 16 |
17 namespace dart { | 17 namespace dart { |
18 | 18 |
19 DECLARE_FLAG(bool, inline_alloc); | 19 DECLARE_FLAG(bool, inline_alloc); |
20 | 20 |
21 | |
22 class DirectCallRelocation : public AssemblerFixup { | 21 class DirectCallRelocation : public AssemblerFixup { |
23 public: | 22 public: |
24 void Process(const MemoryRegion& region, intptr_t position) { | 23 void Process(const MemoryRegion& region, intptr_t position) { |
25 // Direct calls are relative to the following instruction on x86. | 24 // Direct calls are relative to the following instruction on x86. |
26 int32_t pointer = region.Load<int32_t>(position); | 25 int32_t pointer = region.Load<int32_t>(position); |
27 int32_t delta = region.start() + position + sizeof(int32_t); | 26 int32_t delta = region.start() + position + sizeof(int32_t); |
28 region.Store<int32_t>(position, pointer - delta); | 27 region.Store<int32_t>(position, pointer - delta); |
29 } | 28 } |
30 | 29 |
31 virtual bool IsPointerOffset() const { return false; } | 30 virtual bool IsPointerOffset() const { return false; } |
32 }; | 31 }; |
33 | 32 |
34 | |
35 int32_t Assembler::jit_cookie() { | 33 int32_t Assembler::jit_cookie() { |
36 if (jit_cookie_ == 0) { | 34 if (jit_cookie_ == 0) { |
37 jit_cookie_ = | 35 jit_cookie_ = |
38 static_cast<int32_t>(Isolate::Current()->random()->NextUInt32()); | 36 static_cast<int32_t>(Isolate::Current()->random()->NextUInt32()); |
39 } | 37 } |
40 return jit_cookie_; | 38 return jit_cookie_; |
41 } | 39 } |
42 | 40 |
43 | |
44 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 41 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
45 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); | 42 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); |
46 } | 43 } |
47 | 44 |
48 | |
49 void Assembler::call(Register reg) { | 45 void Assembler::call(Register reg) { |
50 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 46 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
51 EmitUint8(0xFF); | 47 EmitUint8(0xFF); |
52 EmitRegisterOperand(2, reg); | 48 EmitRegisterOperand(2, reg); |
53 } | 49 } |
54 | 50 |
55 | |
56 void Assembler::call(const Address& address) { | 51 void Assembler::call(const Address& address) { |
57 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 52 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
58 EmitUint8(0xFF); | 53 EmitUint8(0xFF); |
59 EmitOperand(2, address); | 54 EmitOperand(2, address); |
60 } | 55 } |
61 | 56 |
62 | |
63 void Assembler::call(Label* label) { | 57 void Assembler::call(Label* label) { |
64 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 58 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
65 EmitUint8(0xE8); | 59 EmitUint8(0xE8); |
66 static const int kSize = 5; | 60 static const int kSize = 5; |
67 EmitLabel(label, kSize); | 61 EmitLabel(label, kSize); |
68 } | 62 } |
69 | 63 |
70 | |
71 void Assembler::call(const ExternalLabel* label) { | 64 void Assembler::call(const ExternalLabel* label) { |
72 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 65 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
73 intptr_t call_start = buffer_.GetPosition(); | 66 intptr_t call_start = buffer_.GetPosition(); |
74 EmitUint8(0xE8); | 67 EmitUint8(0xE8); |
75 EmitFixup(new DirectCallRelocation()); | 68 EmitFixup(new DirectCallRelocation()); |
76 EmitInt32(label->address()); | 69 EmitInt32(label->address()); |
77 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); | 70 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
78 } | 71 } |
79 | 72 |
80 | |
81 void Assembler::pushl(Register reg) { | 73 void Assembler::pushl(Register reg) { |
82 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 74 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
83 EmitUint8(0x50 + reg); | 75 EmitUint8(0x50 + reg); |
84 } | 76 } |
85 | 77 |
86 | |
87 void Assembler::pushl(const Address& address) { | 78 void Assembler::pushl(const Address& address) { |
88 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 79 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
89 EmitUint8(0xFF); | 80 EmitUint8(0xFF); |
90 EmitOperand(6, address); | 81 EmitOperand(6, address); |
91 } | 82 } |
92 | 83 |
93 | |
94 void Assembler::pushl(const Immediate& imm) { | 84 void Assembler::pushl(const Immediate& imm) { |
95 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 85 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
96 if (imm.is_int8()) { | 86 if (imm.is_int8()) { |
97 EmitUint8(0x6A); | 87 EmitUint8(0x6A); |
98 EmitUint8(imm.value() & 0xFF); | 88 EmitUint8(imm.value() & 0xFF); |
99 } else { | 89 } else { |
100 EmitUint8(0x68); | 90 EmitUint8(0x68); |
101 EmitImmediate(imm); | 91 EmitImmediate(imm); |
102 } | 92 } |
103 } | 93 } |
104 | 94 |
105 | |
106 void Assembler::popl(Register reg) { | 95 void Assembler::popl(Register reg) { |
107 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 96 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
108 EmitUint8(0x58 + reg); | 97 EmitUint8(0x58 + reg); |
109 } | 98 } |
110 | 99 |
111 | |
112 void Assembler::popl(const Address& address) { | 100 void Assembler::popl(const Address& address) { |
113 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 101 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
114 EmitUint8(0x8F); | 102 EmitUint8(0x8F); |
115 EmitOperand(0, address); | 103 EmitOperand(0, address); |
116 } | 104 } |
117 | 105 |
118 | |
119 void Assembler::pushal() { | 106 void Assembler::pushal() { |
120 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 107 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
121 EmitUint8(0x60); | 108 EmitUint8(0x60); |
122 } | 109 } |
123 | 110 |
124 | |
125 void Assembler::popal() { | 111 void Assembler::popal() { |
126 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 112 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
127 EmitUint8(0x61); | 113 EmitUint8(0x61); |
128 } | 114 } |
129 | 115 |
130 | |
131 void Assembler::setcc(Condition condition, ByteRegister dst) { | 116 void Assembler::setcc(Condition condition, ByteRegister dst) { |
132 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 117 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
133 EmitUint8(0x0F); | 118 EmitUint8(0x0F); |
134 EmitUint8(0x90 + condition); | 119 EmitUint8(0x90 + condition); |
135 EmitUint8(0xC0 + dst); | 120 EmitUint8(0xC0 + dst); |
136 } | 121 } |
137 | 122 |
138 | |
139 void Assembler::movl(Register dst, const Immediate& imm) { | 123 void Assembler::movl(Register dst, const Immediate& imm) { |
140 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 124 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
141 EmitUint8(0xB8 + dst); | 125 EmitUint8(0xB8 + dst); |
142 EmitImmediate(imm); | 126 EmitImmediate(imm); |
143 } | 127 } |
144 | 128 |
145 | |
146 void Assembler::movl(Register dst, Register src) { | 129 void Assembler::movl(Register dst, Register src) { |
147 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 130 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
148 EmitUint8(0x89); | 131 EmitUint8(0x89); |
149 EmitRegisterOperand(src, dst); | 132 EmitRegisterOperand(src, dst); |
150 } | 133 } |
151 | 134 |
152 | |
153 void Assembler::movl(Register dst, const Address& src) { | 135 void Assembler::movl(Register dst, const Address& src) { |
154 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 136 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
155 EmitUint8(0x8B); | 137 EmitUint8(0x8B); |
156 EmitOperand(dst, src); | 138 EmitOperand(dst, src); |
157 } | 139 } |
158 | 140 |
159 | |
160 void Assembler::movl(const Address& dst, Register src) { | 141 void Assembler::movl(const Address& dst, Register src) { |
161 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 142 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
162 EmitUint8(0x89); | 143 EmitUint8(0x89); |
163 EmitOperand(src, dst); | 144 EmitOperand(src, dst); |
164 } | 145 } |
165 | 146 |
166 | |
167 void Assembler::movl(const Address& dst, const Immediate& imm) { | 147 void Assembler::movl(const Address& dst, const Immediate& imm) { |
168 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 148 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
169 EmitUint8(0xC7); | 149 EmitUint8(0xC7); |
170 EmitOperand(0, dst); | 150 EmitOperand(0, dst); |
171 EmitImmediate(imm); | 151 EmitImmediate(imm); |
172 } | 152 } |
173 | 153 |
174 | |
175 void Assembler::movzxb(Register dst, ByteRegister src) { | 154 void Assembler::movzxb(Register dst, ByteRegister src) { |
176 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 155 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
177 EmitUint8(0x0F); | 156 EmitUint8(0x0F); |
178 EmitUint8(0xB6); | 157 EmitUint8(0xB6); |
179 EmitRegisterOperand(dst, src); | 158 EmitRegisterOperand(dst, src); |
180 } | 159 } |
181 | 160 |
182 | |
183 void Assembler::movzxb(Register dst, const Address& src) { | 161 void Assembler::movzxb(Register dst, const Address& src) { |
184 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 162 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
185 EmitUint8(0x0F); | 163 EmitUint8(0x0F); |
186 EmitUint8(0xB6); | 164 EmitUint8(0xB6); |
187 EmitOperand(dst, src); | 165 EmitOperand(dst, src); |
188 } | 166 } |
189 | 167 |
190 | |
191 void Assembler::movsxb(Register dst, ByteRegister src) { | 168 void Assembler::movsxb(Register dst, ByteRegister src) { |
192 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 169 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
193 EmitUint8(0x0F); | 170 EmitUint8(0x0F); |
194 EmitUint8(0xBE); | 171 EmitUint8(0xBE); |
195 EmitRegisterOperand(dst, src); | 172 EmitRegisterOperand(dst, src); |
196 } | 173 } |
197 | 174 |
198 | |
199 void Assembler::movsxb(Register dst, const Address& src) { | 175 void Assembler::movsxb(Register dst, const Address& src) { |
200 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 176 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
201 EmitUint8(0x0F); | 177 EmitUint8(0x0F); |
202 EmitUint8(0xBE); | 178 EmitUint8(0xBE); |
203 EmitOperand(dst, src); | 179 EmitOperand(dst, src); |
204 } | 180 } |
205 | 181 |
206 | |
207 void Assembler::movb(Register dst, const Address& src) { | 182 void Assembler::movb(Register dst, const Address& src) { |
208 FATAL("Use movzxb or movsxb instead."); | 183 FATAL("Use movzxb or movsxb instead."); |
209 } | 184 } |
210 | 185 |
211 | |
212 void Assembler::movb(const Address& dst, ByteRegister src) { | 186 void Assembler::movb(const Address& dst, ByteRegister src) { |
213 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 187 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
214 EmitUint8(0x88); | 188 EmitUint8(0x88); |
215 EmitOperand(src, dst); | 189 EmitOperand(src, dst); |
216 } | 190 } |
217 | 191 |
218 | |
219 void Assembler::movb(const Address& dst, const Immediate& imm) { | 192 void Assembler::movb(const Address& dst, const Immediate& imm) { |
220 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 193 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
221 EmitUint8(0xC6); | 194 EmitUint8(0xC6); |
222 EmitOperand(EAX, dst); | 195 EmitOperand(EAX, dst); |
223 ASSERT(imm.is_int8()); | 196 ASSERT(imm.is_int8()); |
224 EmitUint8(imm.value() & 0xFF); | 197 EmitUint8(imm.value() & 0xFF); |
225 } | 198 } |
226 | 199 |
227 | |
228 void Assembler::movzxw(Register dst, Register src) { | 200 void Assembler::movzxw(Register dst, Register src) { |
229 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 201 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
230 EmitUint8(0x0F); | 202 EmitUint8(0x0F); |
231 EmitUint8(0xB7); | 203 EmitUint8(0xB7); |
232 EmitRegisterOperand(dst, src); | 204 EmitRegisterOperand(dst, src); |
233 } | 205 } |
234 | 206 |
235 | |
236 void Assembler::movzxw(Register dst, const Address& src) { | 207 void Assembler::movzxw(Register dst, const Address& src) { |
237 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 208 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
238 EmitUint8(0x0F); | 209 EmitUint8(0x0F); |
239 EmitUint8(0xB7); | 210 EmitUint8(0xB7); |
240 EmitOperand(dst, src); | 211 EmitOperand(dst, src); |
241 } | 212 } |
242 | 213 |
243 | |
244 void Assembler::movsxw(Register dst, Register src) { | 214 void Assembler::movsxw(Register dst, Register src) { |
245 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 215 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
246 EmitUint8(0x0F); | 216 EmitUint8(0x0F); |
247 EmitUint8(0xBF); | 217 EmitUint8(0xBF); |
248 EmitRegisterOperand(dst, src); | 218 EmitRegisterOperand(dst, src); |
249 } | 219 } |
250 | 220 |
251 | |
252 void Assembler::movsxw(Register dst, const Address& src) { | 221 void Assembler::movsxw(Register dst, const Address& src) { |
253 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 222 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
254 EmitUint8(0x0F); | 223 EmitUint8(0x0F); |
255 EmitUint8(0xBF); | 224 EmitUint8(0xBF); |
256 EmitOperand(dst, src); | 225 EmitOperand(dst, src); |
257 } | 226 } |
258 | 227 |
259 | |
260 void Assembler::movw(Register dst, const Address& src) { | 228 void Assembler::movw(Register dst, const Address& src) { |
261 FATAL("Use movzxw or movsxw instead."); | 229 FATAL("Use movzxw or movsxw instead."); |
262 } | 230 } |
263 | 231 |
264 | |
265 void Assembler::movw(const Address& dst, Register src) { | 232 void Assembler::movw(const Address& dst, Register src) { |
266 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 233 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
267 EmitOperandSizeOverride(); | 234 EmitOperandSizeOverride(); |
268 EmitUint8(0x89); | 235 EmitUint8(0x89); |
269 EmitOperand(src, dst); | 236 EmitOperand(src, dst); |
270 } | 237 } |
271 | 238 |
272 | |
273 void Assembler::movw(const Address& dst, const Immediate& imm) { | 239 void Assembler::movw(const Address& dst, const Immediate& imm) { |
274 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 240 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
275 EmitOperandSizeOverride(); | 241 EmitOperandSizeOverride(); |
276 EmitUint8(0xC7); | 242 EmitUint8(0xC7); |
277 EmitOperand(0, dst); | 243 EmitOperand(0, dst); |
278 EmitUint8(imm.value() & 0xFF); | 244 EmitUint8(imm.value() & 0xFF); |
279 EmitUint8((imm.value() >> 8) & 0xFF); | 245 EmitUint8((imm.value() >> 8) & 0xFF); |
280 } | 246 } |
281 | 247 |
282 | |
283 void Assembler::leal(Register dst, const Address& src) { | 248 void Assembler::leal(Register dst, const Address& src) { |
284 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 249 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
285 EmitUint8(0x8D); | 250 EmitUint8(0x8D); |
286 EmitOperand(dst, src); | 251 EmitOperand(dst, src); |
287 } | 252 } |
288 | 253 |
289 | |
290 // Move if not overflow. | 254 // Move if not overflow. |
291 void Assembler::cmovno(Register dst, Register src) { | 255 void Assembler::cmovno(Register dst, Register src) { |
292 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 256 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
293 EmitUint8(0x0F); | 257 EmitUint8(0x0F); |
294 EmitUint8(0x41); | 258 EmitUint8(0x41); |
295 EmitRegisterOperand(dst, src); | 259 EmitRegisterOperand(dst, src); |
296 } | 260 } |
297 | 261 |
298 | |
299 void Assembler::cmove(Register dst, Register src) { | 262 void Assembler::cmove(Register dst, Register src) { |
300 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 263 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
301 EmitUint8(0x0F); | 264 EmitUint8(0x0F); |
302 EmitUint8(0x44); | 265 EmitUint8(0x44); |
303 EmitRegisterOperand(dst, src); | 266 EmitRegisterOperand(dst, src); |
304 } | 267 } |
305 | 268 |
306 | |
307 void Assembler::cmovne(Register dst, Register src) { | 269 void Assembler::cmovne(Register dst, Register src) { |
308 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 270 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
309 EmitUint8(0x0F); | 271 EmitUint8(0x0F); |
310 EmitUint8(0x45); | 272 EmitUint8(0x45); |
311 EmitRegisterOperand(dst, src); | 273 EmitRegisterOperand(dst, src); |
312 } | 274 } |
313 | 275 |
314 | |
315 void Assembler::cmovs(Register dst, Register src) { | 276 void Assembler::cmovs(Register dst, Register src) { |
316 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 277 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
317 EmitUint8(0x0F); | 278 EmitUint8(0x0F); |
318 EmitUint8(0x48); | 279 EmitUint8(0x48); |
319 EmitRegisterOperand(dst, src); | 280 EmitRegisterOperand(dst, src); |
320 } | 281 } |
321 | 282 |
322 | |
323 void Assembler::cmovns(Register dst, Register src) { | 283 void Assembler::cmovns(Register dst, Register src) { |
324 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 284 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
325 EmitUint8(0x0F); | 285 EmitUint8(0x0F); |
326 EmitUint8(0x49); | 286 EmitUint8(0x49); |
327 EmitRegisterOperand(dst, src); | 287 EmitRegisterOperand(dst, src); |
328 } | 288 } |
329 | 289 |
330 | |
331 void Assembler::cmovgel(Register dst, Register src) { | 290 void Assembler::cmovgel(Register dst, Register src) { |
332 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 291 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
333 EmitUint8(0x0F); | 292 EmitUint8(0x0F); |
334 EmitUint8(0x4D); | 293 EmitUint8(0x4D); |
335 EmitRegisterOperand(dst, src); | 294 EmitRegisterOperand(dst, src); |
336 } | 295 } |
337 | 296 |
338 | |
339 void Assembler::cmovlessl(Register dst, Register src) { | 297 void Assembler::cmovlessl(Register dst, Register src) { |
340 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 298 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
341 EmitUint8(0x0F); | 299 EmitUint8(0x0F); |
342 EmitUint8(0x4C); | 300 EmitUint8(0x4C); |
343 EmitRegisterOperand(dst, src); | 301 EmitRegisterOperand(dst, src); |
344 } | 302 } |
345 | 303 |
346 | |
347 void Assembler::rep_movsb() { | 304 void Assembler::rep_movsb() { |
348 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 305 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
349 EmitUint8(0xF3); | 306 EmitUint8(0xF3); |
350 EmitUint8(0xA4); | 307 EmitUint8(0xA4); |
351 } | 308 } |
352 | 309 |
353 | |
354 void Assembler::movss(XmmRegister dst, const Address& src) { | 310 void Assembler::movss(XmmRegister dst, const Address& src) { |
355 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 311 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
356 EmitUint8(0xF3); | 312 EmitUint8(0xF3); |
357 EmitUint8(0x0F); | 313 EmitUint8(0x0F); |
358 EmitUint8(0x10); | 314 EmitUint8(0x10); |
359 EmitOperand(dst, src); | 315 EmitOperand(dst, src); |
360 } | 316 } |
361 | 317 |
362 | |
363 void Assembler::movss(const Address& dst, XmmRegister src) { | 318 void Assembler::movss(const Address& dst, XmmRegister src) { |
364 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 319 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
365 EmitUint8(0xF3); | 320 EmitUint8(0xF3); |
366 EmitUint8(0x0F); | 321 EmitUint8(0x0F); |
367 EmitUint8(0x11); | 322 EmitUint8(0x11); |
368 EmitOperand(src, dst); | 323 EmitOperand(src, dst); |
369 } | 324 } |
370 | 325 |
371 | |
372 void Assembler::movss(XmmRegister dst, XmmRegister src) { | 326 void Assembler::movss(XmmRegister dst, XmmRegister src) { |
373 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 327 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
374 EmitUint8(0xF3); | 328 EmitUint8(0xF3); |
375 EmitUint8(0x0F); | 329 EmitUint8(0x0F); |
376 EmitUint8(0x11); | 330 EmitUint8(0x11); |
377 EmitXmmRegisterOperand(src, dst); | 331 EmitXmmRegisterOperand(src, dst); |
378 } | 332 } |
379 | 333 |
380 | |
381 void Assembler::movd(XmmRegister dst, Register src) { | 334 void Assembler::movd(XmmRegister dst, Register src) { |
382 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 335 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
383 EmitUint8(0x66); | 336 EmitUint8(0x66); |
384 EmitUint8(0x0F); | 337 EmitUint8(0x0F); |
385 EmitUint8(0x6E); | 338 EmitUint8(0x6E); |
386 EmitOperand(dst, Operand(src)); | 339 EmitOperand(dst, Operand(src)); |
387 } | 340 } |
388 | 341 |
389 | |
390 void Assembler::movd(Register dst, XmmRegister src) { | 342 void Assembler::movd(Register dst, XmmRegister src) { |
391 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 343 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
392 EmitUint8(0x66); | 344 EmitUint8(0x66); |
393 EmitUint8(0x0F); | 345 EmitUint8(0x0F); |
394 EmitUint8(0x7E); | 346 EmitUint8(0x7E); |
395 EmitOperand(src, Operand(dst)); | 347 EmitOperand(src, Operand(dst)); |
396 } | 348 } |
397 | 349 |
398 | |
399 void Assembler::movq(const Address& dst, XmmRegister src) { | 350 void Assembler::movq(const Address& dst, XmmRegister src) { |
400 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 351 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
401 EmitUint8(0x66); | 352 EmitUint8(0x66); |
402 EmitUint8(0x0F); | 353 EmitUint8(0x0F); |
403 EmitUint8(0xD6); | 354 EmitUint8(0xD6); |
404 EmitOperand(src, Operand(dst)); | 355 EmitOperand(src, Operand(dst)); |
405 } | 356 } |
406 | 357 |
407 | |
408 void Assembler::movq(XmmRegister dst, const Address& src) { | 358 void Assembler::movq(XmmRegister dst, const Address& src) { |
409 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 359 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
410 EmitUint8(0xF3); | 360 EmitUint8(0xF3); |
411 EmitUint8(0x0F); | 361 EmitUint8(0x0F); |
412 EmitUint8(0x7E); | 362 EmitUint8(0x7E); |
413 EmitOperand(dst, Operand(src)); | 363 EmitOperand(dst, Operand(src)); |
414 } | 364 } |
415 | 365 |
416 | |
417 void Assembler::addss(XmmRegister dst, XmmRegister src) { | 366 void Assembler::addss(XmmRegister dst, XmmRegister src) { |
418 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 367 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
419 EmitUint8(0xF3); | 368 EmitUint8(0xF3); |
420 EmitUint8(0x0F); | 369 EmitUint8(0x0F); |
421 EmitUint8(0x58); | 370 EmitUint8(0x58); |
422 EmitXmmRegisterOperand(dst, src); | 371 EmitXmmRegisterOperand(dst, src); |
423 } | 372 } |
424 | 373 |
425 | |
426 void Assembler::addss(XmmRegister dst, const Address& src) { | 374 void Assembler::addss(XmmRegister dst, const Address& src) { |
427 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 375 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
428 EmitUint8(0xF3); | 376 EmitUint8(0xF3); |
429 EmitUint8(0x0F); | 377 EmitUint8(0x0F); |
430 EmitUint8(0x58); | 378 EmitUint8(0x58); |
431 EmitOperand(dst, src); | 379 EmitOperand(dst, src); |
432 } | 380 } |
433 | 381 |
434 | |
435 void Assembler::subss(XmmRegister dst, XmmRegister src) { | 382 void Assembler::subss(XmmRegister dst, XmmRegister src) { |
436 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 383 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
437 EmitUint8(0xF3); | 384 EmitUint8(0xF3); |
438 EmitUint8(0x0F); | 385 EmitUint8(0x0F); |
439 EmitUint8(0x5C); | 386 EmitUint8(0x5C); |
440 EmitXmmRegisterOperand(dst, src); | 387 EmitXmmRegisterOperand(dst, src); |
441 } | 388 } |
442 | 389 |
443 | |
444 void Assembler::subss(XmmRegister dst, const Address& src) { | 390 void Assembler::subss(XmmRegister dst, const Address& src) { |
445 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 391 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
446 EmitUint8(0xF3); | 392 EmitUint8(0xF3); |
447 EmitUint8(0x0F); | 393 EmitUint8(0x0F); |
448 EmitUint8(0x5C); | 394 EmitUint8(0x5C); |
449 EmitOperand(dst, src); | 395 EmitOperand(dst, src); |
450 } | 396 } |
451 | 397 |
452 | |
453 void Assembler::mulss(XmmRegister dst, XmmRegister src) { | 398 void Assembler::mulss(XmmRegister dst, XmmRegister src) { |
454 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 399 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
455 EmitUint8(0xF3); | 400 EmitUint8(0xF3); |
456 EmitUint8(0x0F); | 401 EmitUint8(0x0F); |
457 EmitUint8(0x59); | 402 EmitUint8(0x59); |
458 EmitXmmRegisterOperand(dst, src); | 403 EmitXmmRegisterOperand(dst, src); |
459 } | 404 } |
460 | 405 |
461 | |
462 void Assembler::mulss(XmmRegister dst, const Address& src) { | 406 void Assembler::mulss(XmmRegister dst, const Address& src) { |
463 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 407 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
464 EmitUint8(0xF3); | 408 EmitUint8(0xF3); |
465 EmitUint8(0x0F); | 409 EmitUint8(0x0F); |
466 EmitUint8(0x59); | 410 EmitUint8(0x59); |
467 EmitOperand(dst, src); | 411 EmitOperand(dst, src); |
468 } | 412 } |
469 | 413 |
470 | |
471 void Assembler::divss(XmmRegister dst, XmmRegister src) { | 414 void Assembler::divss(XmmRegister dst, XmmRegister src) { |
472 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 415 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
473 EmitUint8(0xF3); | 416 EmitUint8(0xF3); |
474 EmitUint8(0x0F); | 417 EmitUint8(0x0F); |
475 EmitUint8(0x5E); | 418 EmitUint8(0x5E); |
476 EmitXmmRegisterOperand(dst, src); | 419 EmitXmmRegisterOperand(dst, src); |
477 } | 420 } |
478 | 421 |
479 | |
480 void Assembler::divss(XmmRegister dst, const Address& src) { | 422 void Assembler::divss(XmmRegister dst, const Address& src) { |
481 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 423 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
482 EmitUint8(0xF3); | 424 EmitUint8(0xF3); |
483 EmitUint8(0x0F); | 425 EmitUint8(0x0F); |
484 EmitUint8(0x5E); | 426 EmitUint8(0x5E); |
485 EmitOperand(dst, src); | 427 EmitOperand(dst, src); |
486 } | 428 } |
487 | 429 |
488 | |
489 void Assembler::flds(const Address& src) { | 430 void Assembler::flds(const Address& src) { |
490 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 431 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
491 EmitUint8(0xD9); | 432 EmitUint8(0xD9); |
492 EmitOperand(0, src); | 433 EmitOperand(0, src); |
493 } | 434 } |
494 | 435 |
495 | |
496 void Assembler::fstps(const Address& dst) { | 436 void Assembler::fstps(const Address& dst) { |
497 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 437 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
498 EmitUint8(0xD9); | 438 EmitUint8(0xD9); |
499 EmitOperand(3, dst); | 439 EmitOperand(3, dst); |
500 } | 440 } |
501 | 441 |
502 | |
503 void Assembler::movsd(XmmRegister dst, const Address& src) { | 442 void Assembler::movsd(XmmRegister dst, const Address& src) { |
504 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 443 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
505 EmitUint8(0xF2); | 444 EmitUint8(0xF2); |
506 EmitUint8(0x0F); | 445 EmitUint8(0x0F); |
507 EmitUint8(0x10); | 446 EmitUint8(0x10); |
508 EmitOperand(dst, src); | 447 EmitOperand(dst, src); |
509 } | 448 } |
510 | 449 |
511 | |
512 void Assembler::movsd(const Address& dst, XmmRegister src) { | 450 void Assembler::movsd(const Address& dst, XmmRegister src) { |
513 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 451 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
514 EmitUint8(0xF2); | 452 EmitUint8(0xF2); |
515 EmitUint8(0x0F); | 453 EmitUint8(0x0F); |
516 EmitUint8(0x11); | 454 EmitUint8(0x11); |
517 EmitOperand(src, dst); | 455 EmitOperand(src, dst); |
518 } | 456 } |
519 | 457 |
520 | |
521 void Assembler::movsd(XmmRegister dst, XmmRegister src) { | 458 void Assembler::movsd(XmmRegister dst, XmmRegister src) { |
522 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 459 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
523 EmitUint8(0xF2); | 460 EmitUint8(0xF2); |
524 EmitUint8(0x0F); | 461 EmitUint8(0x0F); |
525 EmitUint8(0x11); | 462 EmitUint8(0x11); |
526 EmitXmmRegisterOperand(src, dst); | 463 EmitXmmRegisterOperand(src, dst); |
527 } | 464 } |
528 | 465 |
529 | |
530 void Assembler::movaps(XmmRegister dst, XmmRegister src) { | 466 void Assembler::movaps(XmmRegister dst, XmmRegister src) { |
531 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 467 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
532 EmitUint8(0x0F); | 468 EmitUint8(0x0F); |
533 EmitUint8(0x28); | 469 EmitUint8(0x28); |
534 EmitXmmRegisterOperand(dst, src); | 470 EmitXmmRegisterOperand(dst, src); |
535 } | 471 } |
536 | 472 |
537 | |
538 void Assembler::movups(XmmRegister dst, const Address& src) { | 473 void Assembler::movups(XmmRegister dst, const Address& src) { |
539 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 474 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
540 EmitUint8(0x0F); | 475 EmitUint8(0x0F); |
541 EmitUint8(0x10); | 476 EmitUint8(0x10); |
542 EmitOperand(dst, src); | 477 EmitOperand(dst, src); |
543 } | 478 } |
544 | 479 |
545 | |
546 void Assembler::movups(const Address& dst, XmmRegister src) { | 480 void Assembler::movups(const Address& dst, XmmRegister src) { |
547 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 481 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
548 EmitUint8(0x0F); | 482 EmitUint8(0x0F); |
549 EmitUint8(0x11); | 483 EmitUint8(0x11); |
550 EmitOperand(src, dst); | 484 EmitOperand(src, dst); |
551 } | 485 } |
552 | 486 |
553 | |
554 void Assembler::addsd(XmmRegister dst, XmmRegister src) { | 487 void Assembler::addsd(XmmRegister dst, XmmRegister src) { |
555 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 488 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
556 EmitUint8(0xF2); | 489 EmitUint8(0xF2); |
557 EmitUint8(0x0F); | 490 EmitUint8(0x0F); |
558 EmitUint8(0x58); | 491 EmitUint8(0x58); |
559 EmitXmmRegisterOperand(dst, src); | 492 EmitXmmRegisterOperand(dst, src); |
560 } | 493 } |
561 | 494 |
562 | |
563 void Assembler::addsd(XmmRegister dst, const Address& src) { | 495 void Assembler::addsd(XmmRegister dst, const Address& src) { |
564 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 496 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
565 EmitUint8(0xF2); | 497 EmitUint8(0xF2); |
566 EmitUint8(0x0F); | 498 EmitUint8(0x0F); |
567 EmitUint8(0x58); | 499 EmitUint8(0x58); |
568 EmitOperand(dst, src); | 500 EmitOperand(dst, src); |
569 } | 501 } |
570 | 502 |
571 | |
572 void Assembler::addpl(XmmRegister dst, XmmRegister src) { | 503 void Assembler::addpl(XmmRegister dst, XmmRegister src) { |
573 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 504 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
574 EmitUint8(0x66); | 505 EmitUint8(0x66); |
575 EmitUint8(0x0F); | 506 EmitUint8(0x0F); |
576 EmitUint8(0xFE); | 507 EmitUint8(0xFE); |
577 EmitXmmRegisterOperand(dst, src); | 508 EmitXmmRegisterOperand(dst, src); |
578 } | 509 } |
579 | 510 |
580 | |
581 void Assembler::subpl(XmmRegister dst, XmmRegister src) { | 511 void Assembler::subpl(XmmRegister dst, XmmRegister src) { |
582 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 512 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
583 EmitUint8(0x66); | 513 EmitUint8(0x66); |
584 EmitUint8(0x0F); | 514 EmitUint8(0x0F); |
585 EmitUint8(0xFA); | 515 EmitUint8(0xFA); |
586 EmitXmmRegisterOperand(dst, src); | 516 EmitXmmRegisterOperand(dst, src); |
587 } | 517 } |
588 | 518 |
589 | |
590 void Assembler::addps(XmmRegister dst, XmmRegister src) { | 519 void Assembler::addps(XmmRegister dst, XmmRegister src) { |
591 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 520 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
592 EmitUint8(0x0F); | 521 EmitUint8(0x0F); |
593 EmitUint8(0x58); | 522 EmitUint8(0x58); |
594 EmitXmmRegisterOperand(dst, src); | 523 EmitXmmRegisterOperand(dst, src); |
595 } | 524 } |
596 | 525 |
597 | |
598 void Assembler::subps(XmmRegister dst, XmmRegister src) { | 526 void Assembler::subps(XmmRegister dst, XmmRegister src) { |
599 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 527 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
600 EmitUint8(0x0F); | 528 EmitUint8(0x0F); |
601 EmitUint8(0x5C); | 529 EmitUint8(0x5C); |
602 EmitXmmRegisterOperand(dst, src); | 530 EmitXmmRegisterOperand(dst, src); |
603 } | 531 } |
604 | 532 |
605 | |
606 void Assembler::divps(XmmRegister dst, XmmRegister src) { | 533 void Assembler::divps(XmmRegister dst, XmmRegister src) { |
607 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 534 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
608 EmitUint8(0x0F); | 535 EmitUint8(0x0F); |
609 EmitUint8(0x5E); | 536 EmitUint8(0x5E); |
610 EmitXmmRegisterOperand(dst, src); | 537 EmitXmmRegisterOperand(dst, src); |
611 } | 538 } |
612 | 539 |
613 | |
614 void Assembler::mulps(XmmRegister dst, XmmRegister src) { | 540 void Assembler::mulps(XmmRegister dst, XmmRegister src) { |
615 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 541 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
616 EmitUint8(0x0F); | 542 EmitUint8(0x0F); |
617 EmitUint8(0x59); | 543 EmitUint8(0x59); |
618 EmitXmmRegisterOperand(dst, src); | 544 EmitXmmRegisterOperand(dst, src); |
619 } | 545 } |
620 | 546 |
621 | |
622 void Assembler::minps(XmmRegister dst, XmmRegister src) { | 547 void Assembler::minps(XmmRegister dst, XmmRegister src) { |
623 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 548 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
624 EmitUint8(0x0F); | 549 EmitUint8(0x0F); |
625 EmitUint8(0x5D); | 550 EmitUint8(0x5D); |
626 EmitXmmRegisterOperand(dst, src); | 551 EmitXmmRegisterOperand(dst, src); |
627 } | 552 } |
628 | 553 |
629 | |
630 void Assembler::maxps(XmmRegister dst, XmmRegister src) { | 554 void Assembler::maxps(XmmRegister dst, XmmRegister src) { |
631 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 555 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
632 EmitUint8(0x0F); | 556 EmitUint8(0x0F); |
633 EmitUint8(0x5F); | 557 EmitUint8(0x5F); |
634 EmitXmmRegisterOperand(dst, src); | 558 EmitXmmRegisterOperand(dst, src); |
635 } | 559 } |
636 | 560 |
637 | |
638 void Assembler::andps(XmmRegister dst, XmmRegister src) { | 561 void Assembler::andps(XmmRegister dst, XmmRegister src) { |
639 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 562 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
640 EmitUint8(0x0F); | 563 EmitUint8(0x0F); |
641 EmitUint8(0x54); | 564 EmitUint8(0x54); |
642 EmitXmmRegisterOperand(dst, src); | 565 EmitXmmRegisterOperand(dst, src); |
643 } | 566 } |
644 | 567 |
645 | |
646 void Assembler::andps(XmmRegister dst, const Address& src) { | 568 void Assembler::andps(XmmRegister dst, const Address& src) { |
647 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 569 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
648 EmitUint8(0x0F); | 570 EmitUint8(0x0F); |
649 EmitUint8(0x54); | 571 EmitUint8(0x54); |
650 EmitOperand(dst, src); | 572 EmitOperand(dst, src); |
651 } | 573 } |
652 | 574 |
653 | |
654 void Assembler::orps(XmmRegister dst, XmmRegister src) { | 575 void Assembler::orps(XmmRegister dst, XmmRegister src) { |
655 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 576 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
656 EmitUint8(0x0F); | 577 EmitUint8(0x0F); |
657 EmitUint8(0x56); | 578 EmitUint8(0x56); |
658 EmitXmmRegisterOperand(dst, src); | 579 EmitXmmRegisterOperand(dst, src); |
659 } | 580 } |
660 | 581 |
661 | |
662 void Assembler::notps(XmmRegister dst) { | 582 void Assembler::notps(XmmRegister dst) { |
663 static const struct ALIGN16 { | 583 static const struct ALIGN16 { |
664 uint32_t a; | 584 uint32_t a; |
665 uint32_t b; | 585 uint32_t b; |
666 uint32_t c; | 586 uint32_t c; |
667 uint32_t d; | 587 uint32_t d; |
668 } float_not_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; | 588 } float_not_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; |
669 xorps(dst, Address::Absolute(reinterpret_cast<uword>(&float_not_constant))); | 589 xorps(dst, Address::Absolute(reinterpret_cast<uword>(&float_not_constant))); |
670 } | 590 } |
671 | 591 |
672 | |
673 void Assembler::negateps(XmmRegister dst) { | 592 void Assembler::negateps(XmmRegister dst) { |
674 static const struct ALIGN16 { | 593 static const struct ALIGN16 { |
675 uint32_t a; | 594 uint32_t a; |
676 uint32_t b; | 595 uint32_t b; |
677 uint32_t c; | 596 uint32_t c; |
678 uint32_t d; | 597 uint32_t d; |
679 } float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; | 598 } float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; |
680 xorps(dst, | 599 xorps(dst, |
681 Address::Absolute(reinterpret_cast<uword>(&float_negate_constant))); | 600 Address::Absolute(reinterpret_cast<uword>(&float_negate_constant))); |
682 } | 601 } |
683 | 602 |
684 | |
685 void Assembler::absps(XmmRegister dst) { | 603 void Assembler::absps(XmmRegister dst) { |
686 static const struct ALIGN16 { | 604 static const struct ALIGN16 { |
687 uint32_t a; | 605 uint32_t a; |
688 uint32_t b; | 606 uint32_t b; |
689 uint32_t c; | 607 uint32_t c; |
690 uint32_t d; | 608 uint32_t d; |
691 } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}; | 609 } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}; |
692 andps(dst, | 610 andps(dst, |
693 Address::Absolute(reinterpret_cast<uword>(&float_absolute_constant))); | 611 Address::Absolute(reinterpret_cast<uword>(&float_absolute_constant))); |
694 } | 612 } |
695 | 613 |
696 | |
697 void Assembler::zerowps(XmmRegister dst) { | 614 void Assembler::zerowps(XmmRegister dst) { |
698 static const struct ALIGN16 { | 615 static const struct ALIGN16 { |
699 uint32_t a; | 616 uint32_t a; |
700 uint32_t b; | 617 uint32_t b; |
701 uint32_t c; | 618 uint32_t c; |
702 uint32_t d; | 619 uint32_t d; |
703 } float_zerow_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000}; | 620 } float_zerow_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000}; |
704 andps(dst, Address::Absolute(reinterpret_cast<uword>(&float_zerow_constant))); | 621 andps(dst, Address::Absolute(reinterpret_cast<uword>(&float_zerow_constant))); |
705 } | 622 } |
706 | 623 |
707 | |
708 void Assembler::cmppseq(XmmRegister dst, XmmRegister src) { | 624 void Assembler::cmppseq(XmmRegister dst, XmmRegister src) { |
709 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 625 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
710 EmitUint8(0x0F); | 626 EmitUint8(0x0F); |
711 EmitUint8(0xC2); | 627 EmitUint8(0xC2); |
712 EmitXmmRegisterOperand(dst, src); | 628 EmitXmmRegisterOperand(dst, src); |
713 EmitUint8(0x0); | 629 EmitUint8(0x0); |
714 } | 630 } |
715 | 631 |
716 | |
717 void Assembler::cmppsneq(XmmRegister dst, XmmRegister src) { | 632 void Assembler::cmppsneq(XmmRegister dst, XmmRegister src) { |
718 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 633 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
719 EmitUint8(0x0F); | 634 EmitUint8(0x0F); |
720 EmitUint8(0xC2); | 635 EmitUint8(0xC2); |
721 EmitXmmRegisterOperand(dst, src); | 636 EmitXmmRegisterOperand(dst, src); |
722 EmitUint8(0x4); | 637 EmitUint8(0x4); |
723 } | 638 } |
724 | 639 |
725 | |
726 void Assembler::cmppslt(XmmRegister dst, XmmRegister src) { | 640 void Assembler::cmppslt(XmmRegister dst, XmmRegister src) { |
727 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 641 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
728 EmitUint8(0x0F); | 642 EmitUint8(0x0F); |
729 EmitUint8(0xC2); | 643 EmitUint8(0xC2); |
730 EmitXmmRegisterOperand(dst, src); | 644 EmitXmmRegisterOperand(dst, src); |
731 EmitUint8(0x1); | 645 EmitUint8(0x1); |
732 } | 646 } |
733 | 647 |
734 | |
735 void Assembler::cmppsle(XmmRegister dst, XmmRegister src) { | 648 void Assembler::cmppsle(XmmRegister dst, XmmRegister src) { |
736 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 649 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
737 EmitUint8(0x0F); | 650 EmitUint8(0x0F); |
738 EmitUint8(0xC2); | 651 EmitUint8(0xC2); |
739 EmitXmmRegisterOperand(dst, src); | 652 EmitXmmRegisterOperand(dst, src); |
740 EmitUint8(0x2); | 653 EmitUint8(0x2); |
741 } | 654 } |
742 | 655 |
743 | |
744 void Assembler::cmppsnlt(XmmRegister dst, XmmRegister src) { | 656 void Assembler::cmppsnlt(XmmRegister dst, XmmRegister src) { |
745 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 657 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
746 EmitUint8(0x0F); | 658 EmitUint8(0x0F); |
747 EmitUint8(0xC2); | 659 EmitUint8(0xC2); |
748 EmitXmmRegisterOperand(dst, src); | 660 EmitXmmRegisterOperand(dst, src); |
749 EmitUint8(0x5); | 661 EmitUint8(0x5); |
750 } | 662 } |
751 | 663 |
752 | |
753 void Assembler::cmppsnle(XmmRegister dst, XmmRegister src) { | 664 void Assembler::cmppsnle(XmmRegister dst, XmmRegister src) { |
754 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 665 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
755 EmitUint8(0x0F); | 666 EmitUint8(0x0F); |
756 EmitUint8(0xC2); | 667 EmitUint8(0xC2); |
757 EmitXmmRegisterOperand(dst, src); | 668 EmitXmmRegisterOperand(dst, src); |
758 EmitUint8(0x6); | 669 EmitUint8(0x6); |
759 } | 670 } |
760 | 671 |
761 | |
762 void Assembler::sqrtps(XmmRegister dst) { | 672 void Assembler::sqrtps(XmmRegister dst) { |
763 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 673 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
764 EmitUint8(0x0F); | 674 EmitUint8(0x0F); |
765 EmitUint8(0x51); | 675 EmitUint8(0x51); |
766 EmitXmmRegisterOperand(dst, dst); | 676 EmitXmmRegisterOperand(dst, dst); |
767 } | 677 } |
768 | 678 |
769 | |
770 void Assembler::rsqrtps(XmmRegister dst) { | 679 void Assembler::rsqrtps(XmmRegister dst) { |
771 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 680 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
772 EmitUint8(0x0F); | 681 EmitUint8(0x0F); |
773 EmitUint8(0x52); | 682 EmitUint8(0x52); |
774 EmitXmmRegisterOperand(dst, dst); | 683 EmitXmmRegisterOperand(dst, dst); |
775 } | 684 } |
776 | 685 |
777 | |
778 void Assembler::reciprocalps(XmmRegister dst) { | 686 void Assembler::reciprocalps(XmmRegister dst) { |
779 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 687 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
780 EmitUint8(0x0F); | 688 EmitUint8(0x0F); |
781 EmitUint8(0x53); | 689 EmitUint8(0x53); |
782 EmitXmmRegisterOperand(dst, dst); | 690 EmitXmmRegisterOperand(dst, dst); |
783 } | 691 } |
784 | 692 |
785 | |
786 void Assembler::movhlps(XmmRegister dst, XmmRegister src) { | 693 void Assembler::movhlps(XmmRegister dst, XmmRegister src) { |
787 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 694 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
788 EmitUint8(0x0F); | 695 EmitUint8(0x0F); |
789 EmitUint8(0x12); | 696 EmitUint8(0x12); |
790 EmitXmmRegisterOperand(dst, src); | 697 EmitXmmRegisterOperand(dst, src); |
791 } | 698 } |
792 | 699 |
793 | |
794 void Assembler::movlhps(XmmRegister dst, XmmRegister src) { | 700 void Assembler::movlhps(XmmRegister dst, XmmRegister src) { |
795 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 701 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
796 EmitUint8(0x0F); | 702 EmitUint8(0x0F); |
797 EmitUint8(0x16); | 703 EmitUint8(0x16); |
798 EmitXmmRegisterOperand(dst, src); | 704 EmitXmmRegisterOperand(dst, src); |
799 } | 705 } |
800 | 706 |
801 | |
802 void Assembler::unpcklps(XmmRegister dst, XmmRegister src) { | 707 void Assembler::unpcklps(XmmRegister dst, XmmRegister src) { |
803 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 708 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
804 EmitUint8(0x0F); | 709 EmitUint8(0x0F); |
805 EmitUint8(0x14); | 710 EmitUint8(0x14); |
806 EmitXmmRegisterOperand(dst, src); | 711 EmitXmmRegisterOperand(dst, src); |
807 } | 712 } |
808 | 713 |
809 | |
810 void Assembler::unpckhps(XmmRegister dst, XmmRegister src) { | 714 void Assembler::unpckhps(XmmRegister dst, XmmRegister src) { |
811 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 715 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
812 EmitUint8(0x0F); | 716 EmitUint8(0x0F); |
813 EmitUint8(0x15); | 717 EmitUint8(0x15); |
814 EmitXmmRegisterOperand(dst, src); | 718 EmitXmmRegisterOperand(dst, src); |
815 } | 719 } |
816 | 720 |
817 | |
818 void Assembler::unpcklpd(XmmRegister dst, XmmRegister src) { | 721 void Assembler::unpcklpd(XmmRegister dst, XmmRegister src) { |
819 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 722 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
820 EmitUint8(0x66); | 723 EmitUint8(0x66); |
821 EmitUint8(0x0F); | 724 EmitUint8(0x0F); |
822 EmitUint8(0x14); | 725 EmitUint8(0x14); |
823 EmitXmmRegisterOperand(dst, src); | 726 EmitXmmRegisterOperand(dst, src); |
824 } | 727 } |
825 | 728 |
826 | |
827 void Assembler::unpckhpd(XmmRegister dst, XmmRegister src) { | 729 void Assembler::unpckhpd(XmmRegister dst, XmmRegister src) { |
828 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 730 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
829 EmitUint8(0x66); | 731 EmitUint8(0x66); |
830 EmitUint8(0x0F); | 732 EmitUint8(0x0F); |
831 EmitUint8(0x15); | 733 EmitUint8(0x15); |
832 EmitXmmRegisterOperand(dst, src); | 734 EmitXmmRegisterOperand(dst, src); |
833 } | 735 } |
834 | 736 |
835 | |
836 void Assembler::set1ps(XmmRegister dst, Register tmp1, const Immediate& imm) { | 737 void Assembler::set1ps(XmmRegister dst, Register tmp1, const Immediate& imm) { |
837 // Load 32-bit immediate value into tmp1. | 738 // Load 32-bit immediate value into tmp1. |
838 movl(tmp1, imm); | 739 movl(tmp1, imm); |
839 // Move value from tmp1 into dst. | 740 // Move value from tmp1 into dst. |
840 movd(dst, tmp1); | 741 movd(dst, tmp1); |
841 // Broadcast low lane into other three lanes. | 742 // Broadcast low lane into other three lanes. |
842 shufps(dst, dst, Immediate(0x0)); | 743 shufps(dst, dst, Immediate(0x0)); |
843 } | 744 } |
844 | 745 |
845 | |
846 void Assembler::shufps(XmmRegister dst, XmmRegister src, const Immediate& imm) { | 746 void Assembler::shufps(XmmRegister dst, XmmRegister src, const Immediate& imm) { |
847 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 747 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
848 EmitUint8(0x0F); | 748 EmitUint8(0x0F); |
849 EmitUint8(0xC6); | 749 EmitUint8(0xC6); |
850 EmitXmmRegisterOperand(dst, src); | 750 EmitXmmRegisterOperand(dst, src); |
851 ASSERT(imm.is_uint8()); | 751 ASSERT(imm.is_uint8()); |
852 EmitUint8(imm.value()); | 752 EmitUint8(imm.value()); |
853 } | 753 } |
854 | 754 |
855 | |
856 void Assembler::addpd(XmmRegister dst, XmmRegister src) { | 755 void Assembler::addpd(XmmRegister dst, XmmRegister src) { |
857 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 756 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
858 EmitUint8(0x66); | 757 EmitUint8(0x66); |
859 EmitUint8(0x0F); | 758 EmitUint8(0x0F); |
860 EmitUint8(0x58); | 759 EmitUint8(0x58); |
861 EmitXmmRegisterOperand(dst, src); | 760 EmitXmmRegisterOperand(dst, src); |
862 } | 761 } |
863 | 762 |
864 | |
865 void Assembler::negatepd(XmmRegister dst) { | 763 void Assembler::negatepd(XmmRegister dst) { |
866 static const struct ALIGN16 { | 764 static const struct ALIGN16 { |
867 uint64_t a; | 765 uint64_t a; |
868 uint64_t b; | 766 uint64_t b; |
869 } double_negate_constant = {0x8000000000000000LL, 0x8000000000000000LL}; | 767 } double_negate_constant = {0x8000000000000000LL, 0x8000000000000000LL}; |
870 xorpd(dst, | 768 xorpd(dst, |
871 Address::Absolute(reinterpret_cast<uword>(&double_negate_constant))); | 769 Address::Absolute(reinterpret_cast<uword>(&double_negate_constant))); |
872 } | 770 } |
873 | 771 |
874 | |
875 void Assembler::subpd(XmmRegister dst, XmmRegister src) { | 772 void Assembler::subpd(XmmRegister dst, XmmRegister src) { |
876 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 773 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
877 EmitUint8(0x66); | 774 EmitUint8(0x66); |
878 EmitUint8(0x0F); | 775 EmitUint8(0x0F); |
879 EmitUint8(0x5C); | 776 EmitUint8(0x5C); |
880 EmitXmmRegisterOperand(dst, src); | 777 EmitXmmRegisterOperand(dst, src); |
881 } | 778 } |
882 | 779 |
883 | |
884 void Assembler::mulpd(XmmRegister dst, XmmRegister src) { | 780 void Assembler::mulpd(XmmRegister dst, XmmRegister src) { |
885 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 781 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
886 EmitUint8(0x66); | 782 EmitUint8(0x66); |
887 EmitUint8(0x0F); | 783 EmitUint8(0x0F); |
888 EmitUint8(0x59); | 784 EmitUint8(0x59); |
889 EmitXmmRegisterOperand(dst, src); | 785 EmitXmmRegisterOperand(dst, src); |
890 } | 786 } |
891 | 787 |
892 | |
893 void Assembler::divpd(XmmRegister dst, XmmRegister src) { | 788 void Assembler::divpd(XmmRegister dst, XmmRegister src) { |
894 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 789 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
895 EmitUint8(0x66); | 790 EmitUint8(0x66); |
896 EmitUint8(0x0F); | 791 EmitUint8(0x0F); |
897 EmitUint8(0x5E); | 792 EmitUint8(0x5E); |
898 EmitXmmRegisterOperand(dst, src); | 793 EmitXmmRegisterOperand(dst, src); |
899 } | 794 } |
900 | 795 |
901 | |
902 void Assembler::abspd(XmmRegister dst) { | 796 void Assembler::abspd(XmmRegister dst) { |
903 static const struct ALIGN16 { | 797 static const struct ALIGN16 { |
904 uint64_t a; | 798 uint64_t a; |
905 uint64_t b; | 799 uint64_t b; |
906 } double_absolute_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; | 800 } double_absolute_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; |
907 andpd(dst, | 801 andpd(dst, |
908 Address::Absolute(reinterpret_cast<uword>(&double_absolute_constant))); | 802 Address::Absolute(reinterpret_cast<uword>(&double_absolute_constant))); |
909 } | 803 } |
910 | 804 |
911 | |
912 void Assembler::minpd(XmmRegister dst, XmmRegister src) { | 805 void Assembler::minpd(XmmRegister dst, XmmRegister src) { |
913 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 806 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
914 EmitUint8(0x66); | 807 EmitUint8(0x66); |
915 EmitUint8(0x0F); | 808 EmitUint8(0x0F); |
916 EmitUint8(0x5D); | 809 EmitUint8(0x5D); |
917 EmitXmmRegisterOperand(dst, src); | 810 EmitXmmRegisterOperand(dst, src); |
918 } | 811 } |
919 | 812 |
920 | |
921 void Assembler::maxpd(XmmRegister dst, XmmRegister src) { | 813 void Assembler::maxpd(XmmRegister dst, XmmRegister src) { |
922 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 814 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
923 EmitUint8(0x66); | 815 EmitUint8(0x66); |
924 EmitUint8(0x0F); | 816 EmitUint8(0x0F); |
925 EmitUint8(0x5F); | 817 EmitUint8(0x5F); |
926 EmitXmmRegisterOperand(dst, src); | 818 EmitXmmRegisterOperand(dst, src); |
927 } | 819 } |
928 | 820 |
929 | |
930 void Assembler::sqrtpd(XmmRegister dst) { | 821 void Assembler::sqrtpd(XmmRegister dst) { |
931 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 822 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
932 EmitUint8(0x66); | 823 EmitUint8(0x66); |
933 EmitUint8(0x0F); | 824 EmitUint8(0x0F); |
934 EmitUint8(0x51); | 825 EmitUint8(0x51); |
935 EmitXmmRegisterOperand(dst, dst); | 826 EmitXmmRegisterOperand(dst, dst); |
936 } | 827 } |
937 | 828 |
938 | |
939 void Assembler::cvtps2pd(XmmRegister dst, XmmRegister src) { | 829 void Assembler::cvtps2pd(XmmRegister dst, XmmRegister src) { |
940 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 830 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
941 EmitUint8(0x0F); | 831 EmitUint8(0x0F); |
942 EmitUint8(0x5A); | 832 EmitUint8(0x5A); |
943 EmitXmmRegisterOperand(dst, src); | 833 EmitXmmRegisterOperand(dst, src); |
944 } | 834 } |
945 | 835 |
946 | |
947 void Assembler::cvtpd2ps(XmmRegister dst, XmmRegister src) { | 836 void Assembler::cvtpd2ps(XmmRegister dst, XmmRegister src) { |
948 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 837 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
949 EmitUint8(0x66); | 838 EmitUint8(0x66); |
950 EmitUint8(0x0F); | 839 EmitUint8(0x0F); |
951 EmitUint8(0x5A); | 840 EmitUint8(0x5A); |
952 EmitXmmRegisterOperand(dst, src); | 841 EmitXmmRegisterOperand(dst, src); |
953 } | 842 } |
954 | 843 |
955 | |
956 void Assembler::shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm) { | 844 void Assembler::shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm) { |
957 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 845 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
958 EmitUint8(0x66); | 846 EmitUint8(0x66); |
959 EmitUint8(0x0F); | 847 EmitUint8(0x0F); |
960 EmitUint8(0xC6); | 848 EmitUint8(0xC6); |
961 EmitXmmRegisterOperand(dst, src); | 849 EmitXmmRegisterOperand(dst, src); |
962 ASSERT(imm.is_uint8()); | 850 ASSERT(imm.is_uint8()); |
963 EmitUint8(imm.value()); | 851 EmitUint8(imm.value()); |
964 } | 852 } |
965 | 853 |
966 | |
967 void Assembler::subsd(XmmRegister dst, XmmRegister src) { | 854 void Assembler::subsd(XmmRegister dst, XmmRegister src) { |
968 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 855 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
969 EmitUint8(0xF2); | 856 EmitUint8(0xF2); |
970 EmitUint8(0x0F); | 857 EmitUint8(0x0F); |
971 EmitUint8(0x5C); | 858 EmitUint8(0x5C); |
972 EmitXmmRegisterOperand(dst, src); | 859 EmitXmmRegisterOperand(dst, src); |
973 } | 860 } |
974 | 861 |
975 | |
976 void Assembler::subsd(XmmRegister dst, const Address& src) { | 862 void Assembler::subsd(XmmRegister dst, const Address& src) { |
977 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 863 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
978 EmitUint8(0xF2); | 864 EmitUint8(0xF2); |
979 EmitUint8(0x0F); | 865 EmitUint8(0x0F); |
980 EmitUint8(0x5C); | 866 EmitUint8(0x5C); |
981 EmitOperand(dst, src); | 867 EmitOperand(dst, src); |
982 } | 868 } |
983 | 869 |
984 | |
985 void Assembler::mulsd(XmmRegister dst, XmmRegister src) { | 870 void Assembler::mulsd(XmmRegister dst, XmmRegister src) { |
986 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 871 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
987 EmitUint8(0xF2); | 872 EmitUint8(0xF2); |
988 EmitUint8(0x0F); | 873 EmitUint8(0x0F); |
989 EmitUint8(0x59); | 874 EmitUint8(0x59); |
990 EmitXmmRegisterOperand(dst, src); | 875 EmitXmmRegisterOperand(dst, src); |
991 } | 876 } |
992 | 877 |
993 | |
994 void Assembler::mulsd(XmmRegister dst, const Address& src) { | 878 void Assembler::mulsd(XmmRegister dst, const Address& src) { |
995 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 879 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
996 EmitUint8(0xF2); | 880 EmitUint8(0xF2); |
997 EmitUint8(0x0F); | 881 EmitUint8(0x0F); |
998 EmitUint8(0x59); | 882 EmitUint8(0x59); |
999 EmitOperand(dst, src); | 883 EmitOperand(dst, src); |
1000 } | 884 } |
1001 | 885 |
1002 | |
1003 void Assembler::divsd(XmmRegister dst, XmmRegister src) { | 886 void Assembler::divsd(XmmRegister dst, XmmRegister src) { |
1004 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 887 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1005 EmitUint8(0xF2); | 888 EmitUint8(0xF2); |
1006 EmitUint8(0x0F); | 889 EmitUint8(0x0F); |
1007 EmitUint8(0x5E); | 890 EmitUint8(0x5E); |
1008 EmitXmmRegisterOperand(dst, src); | 891 EmitXmmRegisterOperand(dst, src); |
1009 } | 892 } |
1010 | 893 |
1011 | |
1012 void Assembler::divsd(XmmRegister dst, const Address& src) { | 894 void Assembler::divsd(XmmRegister dst, const Address& src) { |
1013 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 895 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1014 EmitUint8(0xF2); | 896 EmitUint8(0xF2); |
1015 EmitUint8(0x0F); | 897 EmitUint8(0x0F); |
1016 EmitUint8(0x5E); | 898 EmitUint8(0x5E); |
1017 EmitOperand(dst, src); | 899 EmitOperand(dst, src); |
1018 } | 900 } |
1019 | 901 |
1020 | |
1021 void Assembler::cvtsi2ss(XmmRegister dst, Register src) { | 902 void Assembler::cvtsi2ss(XmmRegister dst, Register src) { |
1022 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 903 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1023 EmitUint8(0xF3); | 904 EmitUint8(0xF3); |
1024 EmitUint8(0x0F); | 905 EmitUint8(0x0F); |
1025 EmitUint8(0x2A); | 906 EmitUint8(0x2A); |
1026 EmitOperand(dst, Operand(src)); | 907 EmitOperand(dst, Operand(src)); |
1027 } | 908 } |
1028 | 909 |
1029 | |
1030 void Assembler::cvtsi2sd(XmmRegister dst, Register src) { | 910 void Assembler::cvtsi2sd(XmmRegister dst, Register src) { |
1031 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 911 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1032 EmitUint8(0xF2); | 912 EmitUint8(0xF2); |
1033 EmitUint8(0x0F); | 913 EmitUint8(0x0F); |
1034 EmitUint8(0x2A); | 914 EmitUint8(0x2A); |
1035 EmitOperand(dst, Operand(src)); | 915 EmitOperand(dst, Operand(src)); |
1036 } | 916 } |
1037 | 917 |
1038 | |
1039 void Assembler::cvtss2si(Register dst, XmmRegister src) { | 918 void Assembler::cvtss2si(Register dst, XmmRegister src) { |
1040 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 919 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1041 EmitUint8(0xF3); | 920 EmitUint8(0xF3); |
1042 EmitUint8(0x0F); | 921 EmitUint8(0x0F); |
1043 EmitUint8(0x2D); | 922 EmitUint8(0x2D); |
1044 EmitXmmRegisterOperand(dst, src); | 923 EmitXmmRegisterOperand(dst, src); |
1045 } | 924 } |
1046 | 925 |
1047 | |
1048 void Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) { | 926 void Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) { |
1049 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 927 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1050 EmitUint8(0xF3); | 928 EmitUint8(0xF3); |
1051 EmitUint8(0x0F); | 929 EmitUint8(0x0F); |
1052 EmitUint8(0x5A); | 930 EmitUint8(0x5A); |
1053 EmitXmmRegisterOperand(dst, src); | 931 EmitXmmRegisterOperand(dst, src); |
1054 } | 932 } |
1055 | 933 |
1056 | |
1057 void Assembler::cvtsd2si(Register dst, XmmRegister src) { | 934 void Assembler::cvtsd2si(Register dst, XmmRegister src) { |
1058 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 935 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1059 EmitUint8(0xF2); | 936 EmitUint8(0xF2); |
1060 EmitUint8(0x0F); | 937 EmitUint8(0x0F); |
1061 EmitUint8(0x2D); | 938 EmitUint8(0x2D); |
1062 EmitXmmRegisterOperand(dst, src); | 939 EmitXmmRegisterOperand(dst, src); |
1063 } | 940 } |
1064 | 941 |
1065 | |
1066 void Assembler::cvttss2si(Register dst, XmmRegister src) { | 942 void Assembler::cvttss2si(Register dst, XmmRegister src) { |
1067 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 943 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1068 EmitUint8(0xF3); | 944 EmitUint8(0xF3); |
1069 EmitUint8(0x0F); | 945 EmitUint8(0x0F); |
1070 EmitUint8(0x2C); | 946 EmitUint8(0x2C); |
1071 EmitXmmRegisterOperand(dst, src); | 947 EmitXmmRegisterOperand(dst, src); |
1072 } | 948 } |
1073 | 949 |
1074 | |
1075 void Assembler::cvttsd2si(Register dst, XmmRegister src) { | 950 void Assembler::cvttsd2si(Register dst, XmmRegister src) { |
1076 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 951 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1077 EmitUint8(0xF2); | 952 EmitUint8(0xF2); |
1078 EmitUint8(0x0F); | 953 EmitUint8(0x0F); |
1079 EmitUint8(0x2C); | 954 EmitUint8(0x2C); |
1080 EmitXmmRegisterOperand(dst, src); | 955 EmitXmmRegisterOperand(dst, src); |
1081 } | 956 } |
1082 | 957 |
1083 | |
1084 void Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) { | 958 void Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) { |
1085 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 959 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1086 EmitUint8(0xF2); | 960 EmitUint8(0xF2); |
1087 EmitUint8(0x0F); | 961 EmitUint8(0x0F); |
1088 EmitUint8(0x5A); | 962 EmitUint8(0x5A); |
1089 EmitXmmRegisterOperand(dst, src); | 963 EmitXmmRegisterOperand(dst, src); |
1090 } | 964 } |
1091 | 965 |
1092 | |
1093 void Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) { | 966 void Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) { |
1094 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 967 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1095 EmitUint8(0xF3); | 968 EmitUint8(0xF3); |
1096 EmitUint8(0x0F); | 969 EmitUint8(0x0F); |
1097 EmitUint8(0xE6); | 970 EmitUint8(0xE6); |
1098 EmitXmmRegisterOperand(dst, src); | 971 EmitXmmRegisterOperand(dst, src); |
1099 } | 972 } |
1100 | 973 |
1101 | |
1102 void Assembler::comiss(XmmRegister a, XmmRegister b) { | 974 void Assembler::comiss(XmmRegister a, XmmRegister b) { |
1103 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 975 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1104 EmitUint8(0x0F); | 976 EmitUint8(0x0F); |
1105 EmitUint8(0x2F); | 977 EmitUint8(0x2F); |
1106 EmitXmmRegisterOperand(a, b); | 978 EmitXmmRegisterOperand(a, b); |
1107 } | 979 } |
1108 | 980 |
1109 | |
1110 void Assembler::comisd(XmmRegister a, XmmRegister b) { | 981 void Assembler::comisd(XmmRegister a, XmmRegister b) { |
1111 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 982 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1112 EmitUint8(0x66); | 983 EmitUint8(0x66); |
1113 EmitUint8(0x0F); | 984 EmitUint8(0x0F); |
1114 EmitUint8(0x2F); | 985 EmitUint8(0x2F); |
1115 EmitXmmRegisterOperand(a, b); | 986 EmitXmmRegisterOperand(a, b); |
1116 } | 987 } |
1117 | 988 |
1118 | |
1119 void Assembler::movmskpd(Register dst, XmmRegister src) { | 989 void Assembler::movmskpd(Register dst, XmmRegister src) { |
1120 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 990 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1121 EmitUint8(0x66); | 991 EmitUint8(0x66); |
1122 EmitUint8(0x0F); | 992 EmitUint8(0x0F); |
1123 EmitUint8(0x50); | 993 EmitUint8(0x50); |
1124 EmitXmmRegisterOperand(dst, src); | 994 EmitXmmRegisterOperand(dst, src); |
1125 } | 995 } |
1126 | 996 |
1127 | |
1128 void Assembler::movmskps(Register dst, XmmRegister src) { | 997 void Assembler::movmskps(Register dst, XmmRegister src) { |
1129 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 998 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1130 EmitUint8(0x0F); | 999 EmitUint8(0x0F); |
1131 EmitUint8(0x50); | 1000 EmitUint8(0x50); |
1132 EmitXmmRegisterOperand(dst, src); | 1001 EmitXmmRegisterOperand(dst, src); |
1133 } | 1002 } |
1134 | 1003 |
1135 | |
1136 void Assembler::sqrtsd(XmmRegister dst, XmmRegister src) { | 1004 void Assembler::sqrtsd(XmmRegister dst, XmmRegister src) { |
1137 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1005 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1138 EmitUint8(0xF2); | 1006 EmitUint8(0xF2); |
1139 EmitUint8(0x0F); | 1007 EmitUint8(0x0F); |
1140 EmitUint8(0x51); | 1008 EmitUint8(0x51); |
1141 EmitXmmRegisterOperand(dst, src); | 1009 EmitXmmRegisterOperand(dst, src); |
1142 } | 1010 } |
1143 | 1011 |
1144 | |
1145 void Assembler::sqrtss(XmmRegister dst, XmmRegister src) { | 1012 void Assembler::sqrtss(XmmRegister dst, XmmRegister src) { |
1146 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1013 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1147 EmitUint8(0xF3); | 1014 EmitUint8(0xF3); |
1148 EmitUint8(0x0F); | 1015 EmitUint8(0x0F); |
1149 EmitUint8(0x51); | 1016 EmitUint8(0x51); |
1150 EmitXmmRegisterOperand(dst, src); | 1017 EmitXmmRegisterOperand(dst, src); |
1151 } | 1018 } |
1152 | 1019 |
1153 | |
1154 void Assembler::xorpd(XmmRegister dst, const Address& src) { | 1020 void Assembler::xorpd(XmmRegister dst, const Address& src) { |
1155 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1021 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1156 EmitUint8(0x66); | 1022 EmitUint8(0x66); |
1157 EmitUint8(0x0F); | 1023 EmitUint8(0x0F); |
1158 EmitUint8(0x57); | 1024 EmitUint8(0x57); |
1159 EmitOperand(dst, src); | 1025 EmitOperand(dst, src); |
1160 } | 1026 } |
1161 | 1027 |
1162 | |
1163 void Assembler::xorpd(XmmRegister dst, XmmRegister src) { | 1028 void Assembler::xorpd(XmmRegister dst, XmmRegister src) { |
1164 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1029 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1165 EmitUint8(0x66); | 1030 EmitUint8(0x66); |
1166 EmitUint8(0x0F); | 1031 EmitUint8(0x0F); |
1167 EmitUint8(0x57); | 1032 EmitUint8(0x57); |
1168 EmitXmmRegisterOperand(dst, src); | 1033 EmitXmmRegisterOperand(dst, src); |
1169 } | 1034 } |
1170 | 1035 |
1171 | |
1172 void Assembler::orpd(XmmRegister dst, XmmRegister src) { | 1036 void Assembler::orpd(XmmRegister dst, XmmRegister src) { |
1173 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1037 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1174 EmitUint8(0x66); | 1038 EmitUint8(0x66); |
1175 EmitUint8(0x0F); | 1039 EmitUint8(0x0F); |
1176 EmitUint8(0x56); | 1040 EmitUint8(0x56); |
1177 EmitXmmRegisterOperand(dst, src); | 1041 EmitXmmRegisterOperand(dst, src); |
1178 } | 1042 } |
1179 | 1043 |
1180 | |
1181 void Assembler::xorps(XmmRegister dst, const Address& src) { | 1044 void Assembler::xorps(XmmRegister dst, const Address& src) { |
1182 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1045 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1183 EmitUint8(0x0F); | 1046 EmitUint8(0x0F); |
1184 EmitUint8(0x57); | 1047 EmitUint8(0x57); |
1185 EmitOperand(dst, src); | 1048 EmitOperand(dst, src); |
1186 } | 1049 } |
1187 | 1050 |
1188 | |
1189 void Assembler::xorps(XmmRegister dst, XmmRegister src) { | 1051 void Assembler::xorps(XmmRegister dst, XmmRegister src) { |
1190 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1052 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1191 EmitUint8(0x0F); | 1053 EmitUint8(0x0F); |
1192 EmitUint8(0x57); | 1054 EmitUint8(0x57); |
1193 EmitXmmRegisterOperand(dst, src); | 1055 EmitXmmRegisterOperand(dst, src); |
1194 } | 1056 } |
1195 | 1057 |
1196 | |
1197 void Assembler::andpd(XmmRegister dst, const Address& src) { | 1058 void Assembler::andpd(XmmRegister dst, const Address& src) { |
1198 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1059 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1199 EmitUint8(0x66); | 1060 EmitUint8(0x66); |
1200 EmitUint8(0x0F); | 1061 EmitUint8(0x0F); |
1201 EmitUint8(0x54); | 1062 EmitUint8(0x54); |
1202 EmitOperand(dst, src); | 1063 EmitOperand(dst, src); |
1203 } | 1064 } |
1204 | 1065 |
1205 | |
1206 void Assembler::andpd(XmmRegister dst, XmmRegister src) { | 1066 void Assembler::andpd(XmmRegister dst, XmmRegister src) { |
1207 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1067 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1208 EmitUint8(0x66); | 1068 EmitUint8(0x66); |
1209 EmitUint8(0x0F); | 1069 EmitUint8(0x0F); |
1210 EmitUint8(0x54); | 1070 EmitUint8(0x54); |
1211 EmitXmmRegisterOperand(dst, src); | 1071 EmitXmmRegisterOperand(dst, src); |
1212 } | 1072 } |
1213 | 1073 |
1214 | |
1215 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) { | 1074 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) { |
1216 ASSERT(TargetCPUFeatures::sse4_1_supported()); | 1075 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
1217 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1076 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1218 EmitUint8(0x66); | 1077 EmitUint8(0x66); |
1219 EmitUint8(0x0F); | 1078 EmitUint8(0x0F); |
1220 EmitUint8(0x3A); | 1079 EmitUint8(0x3A); |
1221 EmitUint8(0x16); | 1080 EmitUint8(0x16); |
1222 EmitOperand(src, Operand(dst)); | 1081 EmitOperand(src, Operand(dst)); |
1223 ASSERT(imm.is_uint8()); | 1082 ASSERT(imm.is_uint8()); |
1224 EmitUint8(imm.value()); | 1083 EmitUint8(imm.value()); |
1225 } | 1084 } |
1226 | 1085 |
1227 | |
1228 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) { | 1086 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) { |
1229 ASSERT(TargetCPUFeatures::sse4_1_supported()); | 1087 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
1230 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1088 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1231 EmitUint8(0x66); | 1089 EmitUint8(0x66); |
1232 EmitUint8(0x0F); | 1090 EmitUint8(0x0F); |
1233 EmitUint8(0x38); | 1091 EmitUint8(0x38); |
1234 EmitUint8(0x25); | 1092 EmitUint8(0x25); |
1235 EmitXmmRegisterOperand(dst, src); | 1093 EmitXmmRegisterOperand(dst, src); |
1236 } | 1094 } |
1237 | 1095 |
1238 | |
1239 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) { | 1096 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) { |
1240 ASSERT(TargetCPUFeatures::sse4_1_supported()); | 1097 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
1241 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1098 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1242 EmitUint8(0x66); | 1099 EmitUint8(0x66); |
1243 EmitUint8(0x0F); | 1100 EmitUint8(0x0F); |
1244 EmitUint8(0x38); | 1101 EmitUint8(0x38); |
1245 EmitUint8(0x29); | 1102 EmitUint8(0x29); |
1246 EmitXmmRegisterOperand(dst, src); | 1103 EmitXmmRegisterOperand(dst, src); |
1247 } | 1104 } |
1248 | 1105 |
1249 | |
1250 void Assembler::pxor(XmmRegister dst, XmmRegister src) { | 1106 void Assembler::pxor(XmmRegister dst, XmmRegister src) { |
1251 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1107 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1252 EmitUint8(0x66); | 1108 EmitUint8(0x66); |
1253 EmitUint8(0x0F); | 1109 EmitUint8(0x0F); |
1254 EmitUint8(0xEF); | 1110 EmitUint8(0xEF); |
1255 EmitXmmRegisterOperand(dst, src); | 1111 EmitXmmRegisterOperand(dst, src); |
1256 } | 1112 } |
1257 | 1113 |
1258 | |
1259 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { | 1114 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { |
1260 ASSERT(TargetCPUFeatures::sse4_1_supported()); | 1115 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
1261 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1116 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1262 EmitUint8(0x66); | 1117 EmitUint8(0x66); |
1263 EmitUint8(0x0F); | 1118 EmitUint8(0x0F); |
1264 EmitUint8(0x3A); | 1119 EmitUint8(0x3A); |
1265 EmitUint8(0x0B); | 1120 EmitUint8(0x0B); |
1266 EmitXmmRegisterOperand(dst, src); | 1121 EmitXmmRegisterOperand(dst, src); |
1267 // Mask precision exeption. | 1122 // Mask precision exeption. |
1268 EmitUint8(static_cast<uint8_t>(mode) | 0x8); | 1123 EmitUint8(static_cast<uint8_t>(mode) | 0x8); |
1269 } | 1124 } |
1270 | 1125 |
1271 | |
1272 void Assembler::fldl(const Address& src) { | 1126 void Assembler::fldl(const Address& src) { |
1273 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1127 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1274 EmitUint8(0xDD); | 1128 EmitUint8(0xDD); |
1275 EmitOperand(0, src); | 1129 EmitOperand(0, src); |
1276 } | 1130 } |
1277 | 1131 |
1278 | |
1279 void Assembler::fstpl(const Address& dst) { | 1132 void Assembler::fstpl(const Address& dst) { |
1280 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1133 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1281 EmitUint8(0xDD); | 1134 EmitUint8(0xDD); |
1282 EmitOperand(3, dst); | 1135 EmitOperand(3, dst); |
1283 } | 1136 } |
1284 | 1137 |
1285 | |
1286 void Assembler::fnstcw(const Address& dst) { | 1138 void Assembler::fnstcw(const Address& dst) { |
1287 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1139 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1288 EmitUint8(0xD9); | 1140 EmitUint8(0xD9); |
1289 EmitOperand(7, dst); | 1141 EmitOperand(7, dst); |
1290 } | 1142 } |
1291 | 1143 |
1292 | |
1293 void Assembler::fldcw(const Address& src) { | 1144 void Assembler::fldcw(const Address& src) { |
1294 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1145 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1295 EmitUint8(0xD9); | 1146 EmitUint8(0xD9); |
1296 EmitOperand(5, src); | 1147 EmitOperand(5, src); |
1297 } | 1148 } |
1298 | 1149 |
1299 | |
1300 void Assembler::fistpl(const Address& dst) { | 1150 void Assembler::fistpl(const Address& dst) { |
1301 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1151 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1302 EmitUint8(0xDF); | 1152 EmitUint8(0xDF); |
1303 EmitOperand(7, dst); | 1153 EmitOperand(7, dst); |
1304 } | 1154 } |
1305 | 1155 |
1306 | |
1307 void Assembler::fistps(const Address& dst) { | 1156 void Assembler::fistps(const Address& dst) { |
1308 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1157 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1309 EmitUint8(0xDB); | 1158 EmitUint8(0xDB); |
1310 EmitOperand(3, dst); | 1159 EmitOperand(3, dst); |
1311 } | 1160 } |
1312 | 1161 |
1313 | |
1314 void Assembler::fildl(const Address& src) { | 1162 void Assembler::fildl(const Address& src) { |
1315 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1163 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1316 EmitUint8(0xDF); | 1164 EmitUint8(0xDF); |
1317 EmitOperand(5, src); | 1165 EmitOperand(5, src); |
1318 } | 1166 } |
1319 | 1167 |
1320 | |
1321 void Assembler::filds(const Address& src) { | 1168 void Assembler::filds(const Address& src) { |
1322 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1169 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1323 EmitUint8(0xDB); | 1170 EmitUint8(0xDB); |
1324 EmitOperand(0, src); | 1171 EmitOperand(0, src); |
1325 } | 1172 } |
1326 | 1173 |
1327 | |
1328 void Assembler::fincstp() { | 1174 void Assembler::fincstp() { |
1329 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1175 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1330 EmitUint8(0xD9); | 1176 EmitUint8(0xD9); |
1331 EmitUint8(0xF7); | 1177 EmitUint8(0xF7); |
1332 } | 1178 } |
1333 | 1179 |
1334 | |
1335 void Assembler::ffree(intptr_t value) { | 1180 void Assembler::ffree(intptr_t value) { |
1336 ASSERT(value < 7); | 1181 ASSERT(value < 7); |
1337 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1182 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1338 EmitUint8(0xDD); | 1183 EmitUint8(0xDD); |
1339 EmitUint8(0xC0 + value); | 1184 EmitUint8(0xC0 + value); |
1340 } | 1185 } |
1341 | 1186 |
1342 | |
1343 void Assembler::fsin() { | 1187 void Assembler::fsin() { |
1344 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1188 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1345 EmitUint8(0xD9); | 1189 EmitUint8(0xD9); |
1346 EmitUint8(0xFE); | 1190 EmitUint8(0xFE); |
1347 } | 1191 } |
1348 | 1192 |
1349 | |
1350 void Assembler::fcos() { | 1193 void Assembler::fcos() { |
1351 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1194 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1352 EmitUint8(0xD9); | 1195 EmitUint8(0xD9); |
1353 EmitUint8(0xFF); | 1196 EmitUint8(0xFF); |
1354 } | 1197 } |
1355 | 1198 |
1356 | |
1357 void Assembler::fsincos() { | 1199 void Assembler::fsincos() { |
1358 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1200 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1359 EmitUint8(0xD9); | 1201 EmitUint8(0xD9); |
1360 EmitUint8(0xFB); | 1202 EmitUint8(0xFB); |
1361 } | 1203 } |
1362 | 1204 |
1363 | |
1364 void Assembler::fptan() { | 1205 void Assembler::fptan() { |
1365 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1206 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1366 EmitUint8(0xD9); | 1207 EmitUint8(0xD9); |
1367 EmitUint8(0xF2); | 1208 EmitUint8(0xF2); |
1368 } | 1209 } |
1369 | 1210 |
1370 | |
1371 void Assembler::xchgl(Register dst, Register src) { | 1211 void Assembler::xchgl(Register dst, Register src) { |
1372 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1212 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1373 EmitUint8(0x87); | 1213 EmitUint8(0x87); |
1374 EmitRegisterOperand(dst, src); | 1214 EmitRegisterOperand(dst, src); |
1375 } | 1215 } |
1376 | 1216 |
1377 | |
1378 void Assembler::cmpl(Register reg, const Immediate& imm) { | 1217 void Assembler::cmpl(Register reg, const Immediate& imm) { |
1379 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1218 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1380 EmitComplex(7, Operand(reg), imm); | 1219 EmitComplex(7, Operand(reg), imm); |
1381 } | 1220 } |
1382 | 1221 |
1383 | |
1384 void Assembler::cmpl(Register reg0, Register reg1) { | 1222 void Assembler::cmpl(Register reg0, Register reg1) { |
1385 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1223 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1386 EmitUint8(0x3B); | 1224 EmitUint8(0x3B); |
1387 EmitOperand(reg0, Operand(reg1)); | 1225 EmitOperand(reg0, Operand(reg1)); |
1388 } | 1226 } |
1389 | 1227 |
1390 | |
1391 void Assembler::cmpl(Register reg, const Address& address) { | 1228 void Assembler::cmpl(Register reg, const Address& address) { |
1392 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1229 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1393 EmitUint8(0x3B); | 1230 EmitUint8(0x3B); |
1394 EmitOperand(reg, address); | 1231 EmitOperand(reg, address); |
1395 } | 1232 } |
1396 | 1233 |
1397 | |
1398 void Assembler::addl(Register dst, Register src) { | 1234 void Assembler::addl(Register dst, Register src) { |
1399 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1235 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1400 EmitUint8(0x03); | 1236 EmitUint8(0x03); |
1401 EmitRegisterOperand(dst, src); | 1237 EmitRegisterOperand(dst, src); |
1402 } | 1238 } |
1403 | 1239 |
1404 | |
1405 void Assembler::addl(Register reg, const Address& address) { | 1240 void Assembler::addl(Register reg, const Address& address) { |
1406 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1241 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1407 EmitUint8(0x03); | 1242 EmitUint8(0x03); |
1408 EmitOperand(reg, address); | 1243 EmitOperand(reg, address); |
1409 } | 1244 } |
1410 | 1245 |
1411 | |
1412 void Assembler::cmpl(const Address& address, Register reg) { | 1246 void Assembler::cmpl(const Address& address, Register reg) { |
1413 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1247 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1414 EmitUint8(0x39); | 1248 EmitUint8(0x39); |
1415 EmitOperand(reg, address); | 1249 EmitOperand(reg, address); |
1416 } | 1250 } |
1417 | 1251 |
1418 | |
1419 void Assembler::cmpl(const Address& address, const Immediate& imm) { | 1252 void Assembler::cmpl(const Address& address, const Immediate& imm) { |
1420 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1253 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1421 EmitComplex(7, address, imm); | 1254 EmitComplex(7, address, imm); |
1422 } | 1255 } |
1423 | 1256 |
1424 | |
1425 void Assembler::cmpw(Register reg, const Address& address) { | 1257 void Assembler::cmpw(Register reg, const Address& address) { |
1426 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1258 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1427 EmitOperandSizeOverride(); | 1259 EmitOperandSizeOverride(); |
1428 EmitUint8(0x3B); | 1260 EmitUint8(0x3B); |
1429 EmitOperand(reg, address); | 1261 EmitOperand(reg, address); |
1430 } | 1262 } |
1431 | 1263 |
1432 | |
1433 void Assembler::cmpw(const Address& address, const Immediate& imm) { | 1264 void Assembler::cmpw(const Address& address, const Immediate& imm) { |
1434 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1265 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1435 EmitOperandSizeOverride(); | 1266 EmitOperandSizeOverride(); |
1436 EmitUint8(0x81); | 1267 EmitUint8(0x81); |
1437 EmitOperand(7, address); | 1268 EmitOperand(7, address); |
1438 EmitUint8(imm.value() & 0xFF); | 1269 EmitUint8(imm.value() & 0xFF); |
1439 EmitUint8((imm.value() >> 8) & 0xFF); | 1270 EmitUint8((imm.value() >> 8) & 0xFF); |
1440 } | 1271 } |
1441 | 1272 |
1442 | |
1443 void Assembler::cmpb(const Address& address, const Immediate& imm) { | 1273 void Assembler::cmpb(const Address& address, const Immediate& imm) { |
1444 ASSERT(imm.is_int8()); | 1274 ASSERT(imm.is_int8()); |
1445 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1275 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1446 EmitUint8(0x80); | 1276 EmitUint8(0x80); |
1447 EmitOperand(7, address); | 1277 EmitOperand(7, address); |
1448 EmitUint8(imm.value() & 0xFF); | 1278 EmitUint8(imm.value() & 0xFF); |
1449 } | 1279 } |
1450 | 1280 |
1451 | |
1452 void Assembler::testl(Register reg1, Register reg2) { | 1281 void Assembler::testl(Register reg1, Register reg2) { |
1453 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1282 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1454 EmitUint8(0x85); | 1283 EmitUint8(0x85); |
1455 EmitRegisterOperand(reg1, reg2); | 1284 EmitRegisterOperand(reg1, reg2); |
1456 } | 1285 } |
1457 | 1286 |
1458 | |
1459 void Assembler::testl(Register reg, const Immediate& immediate) { | 1287 void Assembler::testl(Register reg, const Immediate& immediate) { |
1460 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1288 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1461 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) | 1289 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) |
1462 // we only test the byte register to keep the encoding short. | 1290 // we only test the byte register to keep the encoding short. |
1463 if (immediate.is_uint8() && reg < 4) { | 1291 if (immediate.is_uint8() && reg < 4) { |
1464 // Use zero-extended 8-bit immediate. | 1292 // Use zero-extended 8-bit immediate. |
1465 if (reg == EAX) { | 1293 if (reg == EAX) { |
1466 EmitUint8(0xA8); | 1294 EmitUint8(0xA8); |
1467 } else { | 1295 } else { |
1468 EmitUint8(0xF6); | 1296 EmitUint8(0xF6); |
1469 EmitUint8(0xC0 + reg); | 1297 EmitUint8(0xC0 + reg); |
1470 } | 1298 } |
1471 EmitUint8(immediate.value() & 0xFF); | 1299 EmitUint8(immediate.value() & 0xFF); |
1472 } else if (reg == EAX) { | 1300 } else if (reg == EAX) { |
1473 // Use short form if the destination is EAX. | 1301 // Use short form if the destination is EAX. |
1474 EmitUint8(0xA9); | 1302 EmitUint8(0xA9); |
1475 EmitImmediate(immediate); | 1303 EmitImmediate(immediate); |
1476 } else { | 1304 } else { |
1477 EmitUint8(0xF7); | 1305 EmitUint8(0xF7); |
1478 EmitOperand(0, Operand(reg)); | 1306 EmitOperand(0, Operand(reg)); |
1479 EmitImmediate(immediate); | 1307 EmitImmediate(immediate); |
1480 } | 1308 } |
1481 } | 1309 } |
1482 | 1310 |
1483 | |
1484 void Assembler::testb(const Address& address, const Immediate& imm) { | 1311 void Assembler::testb(const Address& address, const Immediate& imm) { |
1485 ASSERT(imm.is_int8()); | 1312 ASSERT(imm.is_int8()); |
1486 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1313 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1487 EmitUint8(0xF6); | 1314 EmitUint8(0xF6); |
1488 EmitOperand(0, address); | 1315 EmitOperand(0, address); |
1489 EmitUint8(imm.value() & 0xFF); | 1316 EmitUint8(imm.value() & 0xFF); |
1490 } | 1317 } |
1491 | 1318 |
1492 | |
1493 void Assembler::andl(Register dst, Register src) { | 1319 void Assembler::andl(Register dst, Register src) { |
1494 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1320 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1495 EmitUint8(0x23); | 1321 EmitUint8(0x23); |
1496 EmitOperand(dst, Operand(src)); | 1322 EmitOperand(dst, Operand(src)); |
1497 } | 1323 } |
1498 | 1324 |
1499 | |
1500 void Assembler::andl(Register dst, const Immediate& imm) { | 1325 void Assembler::andl(Register dst, const Immediate& imm) { |
1501 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1326 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1502 EmitComplex(4, Operand(dst), imm); | 1327 EmitComplex(4, Operand(dst), imm); |
1503 } | 1328 } |
1504 | 1329 |
1505 | |
1506 void Assembler::andl(Register dst, const Address& address) { | 1330 void Assembler::andl(Register dst, const Address& address) { |
1507 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1331 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1508 EmitUint8(0x23); | 1332 EmitUint8(0x23); |
1509 EmitOperand(dst, address); | 1333 EmitOperand(dst, address); |
1510 } | 1334 } |
1511 | 1335 |
1512 | |
1513 void Assembler::orl(Register dst, Register src) { | 1336 void Assembler::orl(Register dst, Register src) { |
1514 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1337 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1515 EmitUint8(0x0B); | 1338 EmitUint8(0x0B); |
1516 EmitOperand(dst, Operand(src)); | 1339 EmitOperand(dst, Operand(src)); |
1517 } | 1340 } |
1518 | 1341 |
1519 | |
1520 void Assembler::orl(Register dst, const Immediate& imm) { | 1342 void Assembler::orl(Register dst, const Immediate& imm) { |
1521 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1343 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1522 EmitComplex(1, Operand(dst), imm); | 1344 EmitComplex(1, Operand(dst), imm); |
1523 } | 1345 } |
1524 | 1346 |
1525 | |
1526 void Assembler::orl(Register dst, const Address& address) { | 1347 void Assembler::orl(Register dst, const Address& address) { |
1527 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1348 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1528 EmitUint8(0x0B); | 1349 EmitUint8(0x0B); |
1529 EmitOperand(dst, address); | 1350 EmitOperand(dst, address); |
1530 } | 1351 } |
1531 | 1352 |
1532 | |
1533 void Assembler::orl(const Address& address, Register reg) { | 1353 void Assembler::orl(const Address& address, Register reg) { |
1534 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1354 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1535 EmitUint8(0x09); | 1355 EmitUint8(0x09); |
1536 EmitOperand(reg, address); | 1356 EmitOperand(reg, address); |
1537 } | 1357 } |
1538 | 1358 |
1539 | |
1540 void Assembler::xorl(Register dst, Register src) { | 1359 void Assembler::xorl(Register dst, Register src) { |
1541 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1360 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1542 EmitUint8(0x33); | 1361 EmitUint8(0x33); |
1543 EmitOperand(dst, Operand(src)); | 1362 EmitOperand(dst, Operand(src)); |
1544 } | 1363 } |
1545 | 1364 |
1546 | |
1547 void Assembler::xorl(Register dst, const Immediate& imm) { | 1365 void Assembler::xorl(Register dst, const Immediate& imm) { |
1548 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1366 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1549 EmitComplex(6, Operand(dst), imm); | 1367 EmitComplex(6, Operand(dst), imm); |
1550 } | 1368 } |
1551 | 1369 |
1552 | |
1553 void Assembler::xorl(Register dst, const Address& address) { | 1370 void Assembler::xorl(Register dst, const Address& address) { |
1554 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1371 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1555 EmitUint8(0x33); | 1372 EmitUint8(0x33); |
1556 EmitOperand(dst, address); | 1373 EmitOperand(dst, address); |
1557 } | 1374 } |
1558 | 1375 |
1559 | |
1560 void Assembler::addl(Register reg, const Immediate& imm) { | 1376 void Assembler::addl(Register reg, const Immediate& imm) { |
1561 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1377 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1562 EmitComplex(0, Operand(reg), imm); | 1378 EmitComplex(0, Operand(reg), imm); |
1563 } | 1379 } |
1564 | 1380 |
1565 | |
1566 void Assembler::addl(const Address& address, Register reg) { | 1381 void Assembler::addl(const Address& address, Register reg) { |
1567 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1382 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1568 EmitUint8(0x01); | 1383 EmitUint8(0x01); |
1569 EmitOperand(reg, address); | 1384 EmitOperand(reg, address); |
1570 } | 1385 } |
1571 | 1386 |
1572 | |
1573 void Assembler::addl(const Address& address, const Immediate& imm) { | 1387 void Assembler::addl(const Address& address, const Immediate& imm) { |
1574 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1388 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1575 EmitComplex(0, address, imm); | 1389 EmitComplex(0, address, imm); |
1576 } | 1390 } |
1577 | 1391 |
1578 | |
1579 void Assembler::adcl(Register reg, const Immediate& imm) { | 1392 void Assembler::adcl(Register reg, const Immediate& imm) { |
1580 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1393 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1581 EmitComplex(2, Operand(reg), imm); | 1394 EmitComplex(2, Operand(reg), imm); |
1582 } | 1395 } |
1583 | 1396 |
1584 | |
1585 void Assembler::adcl(Register dst, Register src) { | 1397 void Assembler::adcl(Register dst, Register src) { |
1586 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1398 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1587 EmitUint8(0x13); | 1399 EmitUint8(0x13); |
1588 EmitOperand(dst, Operand(src)); | 1400 EmitOperand(dst, Operand(src)); |
1589 } | 1401 } |
1590 | 1402 |
1591 | |
1592 void Assembler::adcl(Register dst, const Address& address) { | 1403 void Assembler::adcl(Register dst, const Address& address) { |
1593 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1404 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1594 EmitUint8(0x13); | 1405 EmitUint8(0x13); |
1595 EmitOperand(dst, address); | 1406 EmitOperand(dst, address); |
1596 } | 1407 } |
1597 | 1408 |
1598 | |
1599 void Assembler::adcl(const Address& address, Register reg) { | 1409 void Assembler::adcl(const Address& address, Register reg) { |
1600 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1410 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1601 EmitUint8(0x11); | 1411 EmitUint8(0x11); |
1602 EmitOperand(reg, address); | 1412 EmitOperand(reg, address); |
1603 } | 1413 } |
1604 | 1414 |
1605 | |
1606 void Assembler::subl(Register dst, Register src) { | 1415 void Assembler::subl(Register dst, Register src) { |
1607 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1416 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1608 EmitUint8(0x2B); | 1417 EmitUint8(0x2B); |
1609 EmitOperand(dst, Operand(src)); | 1418 EmitOperand(dst, Operand(src)); |
1610 } | 1419 } |
1611 | 1420 |
1612 | |
1613 void Assembler::subl(Register reg, const Immediate& imm) { | 1421 void Assembler::subl(Register reg, const Immediate& imm) { |
1614 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1422 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1615 EmitComplex(5, Operand(reg), imm); | 1423 EmitComplex(5, Operand(reg), imm); |
1616 } | 1424 } |
1617 | 1425 |
1618 | |
1619 void Assembler::subl(Register reg, const Address& address) { | 1426 void Assembler::subl(Register reg, const Address& address) { |
1620 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1427 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1621 EmitUint8(0x2B); | 1428 EmitUint8(0x2B); |
1622 EmitOperand(reg, address); | 1429 EmitOperand(reg, address); |
1623 } | 1430 } |
1624 | 1431 |
1625 | |
1626 void Assembler::subl(const Address& address, Register reg) { | 1432 void Assembler::subl(const Address& address, Register reg) { |
1627 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1433 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1628 EmitUint8(0x29); | 1434 EmitUint8(0x29); |
1629 EmitOperand(reg, address); | 1435 EmitOperand(reg, address); |
1630 } | 1436 } |
1631 | 1437 |
1632 | |
1633 void Assembler::cdq() { | 1438 void Assembler::cdq() { |
1634 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1439 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1635 EmitUint8(0x99); | 1440 EmitUint8(0x99); |
1636 } | 1441 } |
1637 | 1442 |
1638 | |
1639 void Assembler::idivl(Register reg) { | 1443 void Assembler::idivl(Register reg) { |
1640 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1444 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1641 EmitUint8(0xF7); | 1445 EmitUint8(0xF7); |
1642 EmitOperand(7, Operand(reg)); | 1446 EmitOperand(7, Operand(reg)); |
1643 } | 1447 } |
1644 | 1448 |
1645 | |
1646 void Assembler::divl(Register reg) { | 1449 void Assembler::divl(Register reg) { |
1647 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1450 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1648 EmitUint8(0xF7); | 1451 EmitUint8(0xF7); |
1649 EmitOperand(6, Operand(reg)); | 1452 EmitOperand(6, Operand(reg)); |
1650 } | 1453 } |
1651 | 1454 |
1652 | |
1653 void Assembler::imull(Register dst, Register src) { | 1455 void Assembler::imull(Register dst, Register src) { |
1654 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1456 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1655 EmitUint8(0x0F); | 1457 EmitUint8(0x0F); |
1656 EmitUint8(0xAF); | 1458 EmitUint8(0xAF); |
1657 EmitOperand(dst, Operand(src)); | 1459 EmitOperand(dst, Operand(src)); |
1658 } | 1460 } |
1659 | 1461 |
1660 | |
1661 void Assembler::imull(Register reg, const Immediate& imm) { | 1462 void Assembler::imull(Register reg, const Immediate& imm) { |
1662 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1463 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1663 EmitUint8(0x69); | 1464 EmitUint8(0x69); |
1664 EmitOperand(reg, Operand(reg)); | 1465 EmitOperand(reg, Operand(reg)); |
1665 EmitImmediate(imm); | 1466 EmitImmediate(imm); |
1666 } | 1467 } |
1667 | 1468 |
1668 | |
1669 void Assembler::imull(Register reg, const Address& address) { | 1469 void Assembler::imull(Register reg, const Address& address) { |
1670 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1470 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1671 EmitUint8(0x0F); | 1471 EmitUint8(0x0F); |
1672 EmitUint8(0xAF); | 1472 EmitUint8(0xAF); |
1673 EmitOperand(reg, address); | 1473 EmitOperand(reg, address); |
1674 } | 1474 } |
1675 | 1475 |
1676 | |
1677 void Assembler::imull(Register reg) { | 1476 void Assembler::imull(Register reg) { |
1678 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1477 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1679 EmitUint8(0xF7); | 1478 EmitUint8(0xF7); |
1680 EmitOperand(5, Operand(reg)); | 1479 EmitOperand(5, Operand(reg)); |
1681 } | 1480 } |
1682 | 1481 |
1683 | |
1684 void Assembler::imull(const Address& address) { | 1482 void Assembler::imull(const Address& address) { |
1685 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1483 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1686 EmitUint8(0xF7); | 1484 EmitUint8(0xF7); |
1687 EmitOperand(5, address); | 1485 EmitOperand(5, address); |
1688 } | 1486 } |
1689 | 1487 |
1690 | |
1691 void Assembler::mull(Register reg) { | 1488 void Assembler::mull(Register reg) { |
1692 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1489 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1693 EmitUint8(0xF7); | 1490 EmitUint8(0xF7); |
1694 EmitOperand(4, Operand(reg)); | 1491 EmitOperand(4, Operand(reg)); |
1695 } | 1492 } |
1696 | 1493 |
1697 | |
1698 void Assembler::mull(const Address& address) { | 1494 void Assembler::mull(const Address& address) { |
1699 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1495 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1700 EmitUint8(0xF7); | 1496 EmitUint8(0xF7); |
1701 EmitOperand(4, address); | 1497 EmitOperand(4, address); |
1702 } | 1498 } |
1703 | 1499 |
1704 | |
1705 void Assembler::sbbl(Register dst, Register src) { | 1500 void Assembler::sbbl(Register dst, Register src) { |
1706 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1501 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1707 EmitUint8(0x1B); | 1502 EmitUint8(0x1B); |
1708 EmitOperand(dst, Operand(src)); | 1503 EmitOperand(dst, Operand(src)); |
1709 } | 1504 } |
1710 | 1505 |
1711 | |
1712 void Assembler::sbbl(Register reg, const Immediate& imm) { | 1506 void Assembler::sbbl(Register reg, const Immediate& imm) { |
1713 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1507 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1714 EmitComplex(3, Operand(reg), imm); | 1508 EmitComplex(3, Operand(reg), imm); |
1715 } | 1509 } |
1716 | 1510 |
1717 | |
1718 void Assembler::sbbl(Register dst, const Address& address) { | 1511 void Assembler::sbbl(Register dst, const Address& address) { |
1719 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1512 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1720 EmitUint8(0x1B); | 1513 EmitUint8(0x1B); |
1721 EmitOperand(dst, address); | 1514 EmitOperand(dst, address); |
1722 } | 1515 } |
1723 | 1516 |
1724 | |
1725 void Assembler::sbbl(const Address& address, Register dst) { | 1517 void Assembler::sbbl(const Address& address, Register dst) { |
1726 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1518 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1727 EmitUint8(0x19); | 1519 EmitUint8(0x19); |
1728 EmitOperand(dst, address); | 1520 EmitOperand(dst, address); |
1729 } | 1521 } |
1730 | 1522 |
1731 | |
1732 void Assembler::incl(Register reg) { | 1523 void Assembler::incl(Register reg) { |
1733 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1524 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1734 EmitUint8(0x40 + reg); | 1525 EmitUint8(0x40 + reg); |
1735 } | 1526 } |
1736 | 1527 |
1737 | |
1738 void Assembler::incl(const Address& address) { | 1528 void Assembler::incl(const Address& address) { |
1739 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1529 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1740 EmitUint8(0xFF); | 1530 EmitUint8(0xFF); |
1741 EmitOperand(0, address); | 1531 EmitOperand(0, address); |
1742 } | 1532 } |
1743 | 1533 |
1744 | |
1745 void Assembler::decl(Register reg) { | 1534 void Assembler::decl(Register reg) { |
1746 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1535 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1747 EmitUint8(0x48 + reg); | 1536 EmitUint8(0x48 + reg); |
1748 } | 1537 } |
1749 | 1538 |
1750 | |
1751 void Assembler::decl(const Address& address) { | 1539 void Assembler::decl(const Address& address) { |
1752 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1540 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1753 EmitUint8(0xFF); | 1541 EmitUint8(0xFF); |
1754 EmitOperand(1, address); | 1542 EmitOperand(1, address); |
1755 } | 1543 } |
1756 | 1544 |
1757 | |
1758 void Assembler::shll(Register reg, const Immediate& imm) { | 1545 void Assembler::shll(Register reg, const Immediate& imm) { |
1759 EmitGenericShift(4, reg, imm); | 1546 EmitGenericShift(4, reg, imm); |
1760 } | 1547 } |
1761 | 1548 |
1762 | |
1763 void Assembler::shll(Register operand, Register shifter) { | 1549 void Assembler::shll(Register operand, Register shifter) { |
1764 EmitGenericShift(4, Operand(operand), shifter); | 1550 EmitGenericShift(4, Operand(operand), shifter); |
1765 } | 1551 } |
1766 | 1552 |
1767 | |
1768 void Assembler::shll(const Address& operand, Register shifter) { | 1553 void Assembler::shll(const Address& operand, Register shifter) { |
1769 EmitGenericShift(4, Operand(operand), shifter); | 1554 EmitGenericShift(4, Operand(operand), shifter); |
1770 } | 1555 } |
1771 | 1556 |
1772 | |
1773 void Assembler::shrl(Register reg, const Immediate& imm) { | 1557 void Assembler::shrl(Register reg, const Immediate& imm) { |
1774 EmitGenericShift(5, reg, imm); | 1558 EmitGenericShift(5, reg, imm); |
1775 } | 1559 } |
1776 | 1560 |
1777 | |
1778 void Assembler::shrl(Register operand, Register shifter) { | 1561 void Assembler::shrl(Register operand, Register shifter) { |
1779 EmitGenericShift(5, Operand(operand), shifter); | 1562 EmitGenericShift(5, Operand(operand), shifter); |
1780 } | 1563 } |
1781 | 1564 |
1782 | |
1783 void Assembler::sarl(Register reg, const Immediate& imm) { | 1565 void Assembler::sarl(Register reg, const Immediate& imm) { |
1784 EmitGenericShift(7, reg, imm); | 1566 EmitGenericShift(7, reg, imm); |
1785 } | 1567 } |
1786 | 1568 |
1787 | |
1788 void Assembler::sarl(Register operand, Register shifter) { | 1569 void Assembler::sarl(Register operand, Register shifter) { |
1789 EmitGenericShift(7, Operand(operand), shifter); | 1570 EmitGenericShift(7, Operand(operand), shifter); |
1790 } | 1571 } |
1791 | 1572 |
1792 | |
1793 void Assembler::sarl(const Address& address, Register shifter) { | 1573 void Assembler::sarl(const Address& address, Register shifter) { |
1794 EmitGenericShift(7, Operand(address), shifter); | 1574 EmitGenericShift(7, Operand(address), shifter); |
1795 } | 1575 } |
1796 | 1576 |
1797 | |
1798 void Assembler::shldl(Register dst, Register src, Register shifter) { | 1577 void Assembler::shldl(Register dst, Register src, Register shifter) { |
1799 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1578 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1800 ASSERT(shifter == ECX); | 1579 ASSERT(shifter == ECX); |
1801 EmitUint8(0x0F); | 1580 EmitUint8(0x0F); |
1802 EmitUint8(0xA5); | 1581 EmitUint8(0xA5); |
1803 EmitRegisterOperand(src, dst); | 1582 EmitRegisterOperand(src, dst); |
1804 } | 1583 } |
1805 | 1584 |
1806 | |
1807 void Assembler::shldl(Register dst, Register src, const Immediate& imm) { | 1585 void Assembler::shldl(Register dst, Register src, const Immediate& imm) { |
1808 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1586 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1809 ASSERT(imm.is_int8()); | 1587 ASSERT(imm.is_int8()); |
1810 EmitUint8(0x0F); | 1588 EmitUint8(0x0F); |
1811 EmitUint8(0xA4); | 1589 EmitUint8(0xA4); |
1812 EmitRegisterOperand(src, dst); | 1590 EmitRegisterOperand(src, dst); |
1813 EmitUint8(imm.value() & 0xFF); | 1591 EmitUint8(imm.value() & 0xFF); |
1814 } | 1592 } |
1815 | 1593 |
1816 | |
1817 void Assembler::shldl(const Address& operand, Register src, Register shifter) { | 1594 void Assembler::shldl(const Address& operand, Register src, Register shifter) { |
1818 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1595 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1819 ASSERT(shifter == ECX); | 1596 ASSERT(shifter == ECX); |
1820 EmitUint8(0x0F); | 1597 EmitUint8(0x0F); |
1821 EmitUint8(0xA5); | 1598 EmitUint8(0xA5); |
1822 EmitOperand(src, Operand(operand)); | 1599 EmitOperand(src, Operand(operand)); |
1823 } | 1600 } |
1824 | 1601 |
1825 | |
1826 void Assembler::shrdl(Register dst, Register src, Register shifter) { | 1602 void Assembler::shrdl(Register dst, Register src, Register shifter) { |
1827 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1603 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1828 ASSERT(shifter == ECX); | 1604 ASSERT(shifter == ECX); |
1829 EmitUint8(0x0F); | 1605 EmitUint8(0x0F); |
1830 EmitUint8(0xAD); | 1606 EmitUint8(0xAD); |
1831 EmitRegisterOperand(src, dst); | 1607 EmitRegisterOperand(src, dst); |
1832 } | 1608 } |
1833 | 1609 |
1834 | |
1835 void Assembler::shrdl(Register dst, Register src, const Immediate& imm) { | 1610 void Assembler::shrdl(Register dst, Register src, const Immediate& imm) { |
1836 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1611 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1837 ASSERT(imm.is_int8()); | 1612 ASSERT(imm.is_int8()); |
1838 EmitUint8(0x0F); | 1613 EmitUint8(0x0F); |
1839 EmitUint8(0xAC); | 1614 EmitUint8(0xAC); |
1840 EmitRegisterOperand(src, dst); | 1615 EmitRegisterOperand(src, dst); |
1841 EmitUint8(imm.value() & 0xFF); | 1616 EmitUint8(imm.value() & 0xFF); |
1842 } | 1617 } |
1843 | 1618 |
1844 | |
1845 void Assembler::shrdl(const Address& dst, Register src, Register shifter) { | 1619 void Assembler::shrdl(const Address& dst, Register src, Register shifter) { |
1846 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1620 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1847 ASSERT(shifter == ECX); | 1621 ASSERT(shifter == ECX); |
1848 EmitUint8(0x0F); | 1622 EmitUint8(0x0F); |
1849 EmitUint8(0xAD); | 1623 EmitUint8(0xAD); |
1850 EmitOperand(src, Operand(dst)); | 1624 EmitOperand(src, Operand(dst)); |
1851 } | 1625 } |
1852 | 1626 |
1853 | |
1854 void Assembler::negl(Register reg) { | 1627 void Assembler::negl(Register reg) { |
1855 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1628 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1856 EmitUint8(0xF7); | 1629 EmitUint8(0xF7); |
1857 EmitOperand(3, Operand(reg)); | 1630 EmitOperand(3, Operand(reg)); |
1858 } | 1631 } |
1859 | 1632 |
1860 | |
1861 void Assembler::notl(Register reg) { | 1633 void Assembler::notl(Register reg) { |
1862 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1634 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1863 EmitUint8(0xF7); | 1635 EmitUint8(0xF7); |
1864 EmitUint8(0xD0 | reg); | 1636 EmitUint8(0xD0 | reg); |
1865 } | 1637 } |
1866 | 1638 |
1867 | |
1868 void Assembler::bsrl(Register dst, Register src) { | 1639 void Assembler::bsrl(Register dst, Register src) { |
1869 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1640 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1870 EmitUint8(0x0F); | 1641 EmitUint8(0x0F); |
1871 EmitUint8(0xBD); | 1642 EmitUint8(0xBD); |
1872 EmitRegisterOperand(dst, src); | 1643 EmitRegisterOperand(dst, src); |
1873 } | 1644 } |
1874 | 1645 |
1875 | |
1876 void Assembler::bt(Register base, Register offset) { | 1646 void Assembler::bt(Register base, Register offset) { |
1877 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1647 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1878 EmitUint8(0x0F); | 1648 EmitUint8(0x0F); |
1879 EmitUint8(0xA3); | 1649 EmitUint8(0xA3); |
1880 EmitRegisterOperand(offset, base); | 1650 EmitRegisterOperand(offset, base); |
1881 } | 1651 } |
1882 | 1652 |
1883 | |
1884 void Assembler::enter(const Immediate& imm) { | 1653 void Assembler::enter(const Immediate& imm) { |
1885 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1654 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1886 EmitUint8(0xC8); | 1655 EmitUint8(0xC8); |
1887 ASSERT(imm.is_uint16()); | 1656 ASSERT(imm.is_uint16()); |
1888 EmitUint8(imm.value() & 0xFF); | 1657 EmitUint8(imm.value() & 0xFF); |
1889 EmitUint8((imm.value() >> 8) & 0xFF); | 1658 EmitUint8((imm.value() >> 8) & 0xFF); |
1890 EmitUint8(0x00); | 1659 EmitUint8(0x00); |
1891 } | 1660 } |
1892 | 1661 |
1893 | |
1894 void Assembler::leave() { | 1662 void Assembler::leave() { |
1895 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1663 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1896 EmitUint8(0xC9); | 1664 EmitUint8(0xC9); |
1897 } | 1665 } |
1898 | 1666 |
1899 | |
1900 void Assembler::ret() { | 1667 void Assembler::ret() { |
1901 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1668 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1902 EmitUint8(0xC3); | 1669 EmitUint8(0xC3); |
1903 } | 1670 } |
1904 | 1671 |
1905 | |
1906 void Assembler::ret(const Immediate& imm) { | 1672 void Assembler::ret(const Immediate& imm) { |
1907 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1673 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1908 EmitUint8(0xC2); | 1674 EmitUint8(0xC2); |
1909 ASSERT(imm.is_uint16()); | 1675 ASSERT(imm.is_uint16()); |
1910 EmitUint8(imm.value() & 0xFF); | 1676 EmitUint8(imm.value() & 0xFF); |
1911 EmitUint8((imm.value() >> 8) & 0xFF); | 1677 EmitUint8((imm.value() >> 8) & 0xFF); |
1912 } | 1678 } |
1913 | 1679 |
1914 | |
1915 void Assembler::nop(int size) { | 1680 void Assembler::nop(int size) { |
1916 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1681 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1917 // There are nops up to size 15, but for now just provide up to size 8. | 1682 // There are nops up to size 15, but for now just provide up to size 8. |
1918 ASSERT(0 < size && size <= MAX_NOP_SIZE); | 1683 ASSERT(0 < size && size <= MAX_NOP_SIZE); |
1919 switch (size) { | 1684 switch (size) { |
1920 case 1: | 1685 case 1: |
1921 EmitUint8(0x90); | 1686 EmitUint8(0x90); |
1922 break; | 1687 break; |
1923 case 2: | 1688 case 2: |
1924 EmitUint8(0x66); | 1689 EmitUint8(0x66); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 EmitUint8(0x00); | 1732 EmitUint8(0x00); |
1968 EmitUint8(0x00); | 1733 EmitUint8(0x00); |
1969 EmitUint8(0x00); | 1734 EmitUint8(0x00); |
1970 EmitUint8(0x00); | 1735 EmitUint8(0x00); |
1971 break; | 1736 break; |
1972 default: | 1737 default: |
1973 UNIMPLEMENTED(); | 1738 UNIMPLEMENTED(); |
1974 } | 1739 } |
1975 } | 1740 } |
1976 | 1741 |
1977 | |
1978 void Assembler::int3() { | 1742 void Assembler::int3() { |
1979 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1743 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1980 EmitUint8(0xCC); | 1744 EmitUint8(0xCC); |
1981 } | 1745 } |
1982 | 1746 |
1983 | |
1984 void Assembler::hlt() { | 1747 void Assembler::hlt() { |
1985 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1748 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1986 EmitUint8(0xF4); | 1749 EmitUint8(0xF4); |
1987 } | 1750 } |
1988 | 1751 |
1989 | |
1990 void Assembler::j(Condition condition, Label* label, bool near) { | 1752 void Assembler::j(Condition condition, Label* label, bool near) { |
1991 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1753 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1992 if (label->IsBound()) { | 1754 if (label->IsBound()) { |
1993 static const int kShortSize = 2; | 1755 static const int kShortSize = 2; |
1994 static const int kLongSize = 6; | 1756 static const int kLongSize = 6; |
1995 intptr_t offset = label->Position() - buffer_.Size(); | 1757 intptr_t offset = label->Position() - buffer_.Size(); |
1996 ASSERT(offset <= 0); | 1758 ASSERT(offset <= 0); |
1997 if (Utils::IsInt(8, offset - kShortSize)) { | 1759 if (Utils::IsInt(8, offset - kShortSize)) { |
1998 EmitUint8(0x70 + condition); | 1760 EmitUint8(0x70 + condition); |
1999 EmitUint8((offset - kShortSize) & 0xFF); | 1761 EmitUint8((offset - kShortSize) & 0xFF); |
2000 } else { | 1762 } else { |
2001 EmitUint8(0x0F); | 1763 EmitUint8(0x0F); |
2002 EmitUint8(0x80 + condition); | 1764 EmitUint8(0x80 + condition); |
2003 EmitInt32(offset - kLongSize); | 1765 EmitInt32(offset - kLongSize); |
2004 } | 1766 } |
2005 } else if (near) { | 1767 } else if (near) { |
2006 EmitUint8(0x70 + condition); | 1768 EmitUint8(0x70 + condition); |
2007 EmitNearLabelLink(label); | 1769 EmitNearLabelLink(label); |
2008 } else { | 1770 } else { |
2009 EmitUint8(0x0F); | 1771 EmitUint8(0x0F); |
2010 EmitUint8(0x80 + condition); | 1772 EmitUint8(0x80 + condition); |
2011 EmitLabelLink(label); | 1773 EmitLabelLink(label); |
2012 } | 1774 } |
2013 } | 1775 } |
2014 | 1776 |
2015 | |
2016 void Assembler::j(Condition condition, const ExternalLabel* label) { | 1777 void Assembler::j(Condition condition, const ExternalLabel* label) { |
2017 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1778 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2018 EmitUint8(0x0F); | 1779 EmitUint8(0x0F); |
2019 EmitUint8(0x80 + condition); | 1780 EmitUint8(0x80 + condition); |
2020 EmitFixup(new DirectCallRelocation()); | 1781 EmitFixup(new DirectCallRelocation()); |
2021 EmitInt32(label->address()); | 1782 EmitInt32(label->address()); |
2022 } | 1783 } |
2023 | 1784 |
2024 | |
2025 void Assembler::jmp(Register reg) { | 1785 void Assembler::jmp(Register reg) { |
2026 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1786 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2027 EmitUint8(0xFF); | 1787 EmitUint8(0xFF); |
2028 EmitRegisterOperand(4, reg); | 1788 EmitRegisterOperand(4, reg); |
2029 } | 1789 } |
2030 | 1790 |
2031 | |
2032 void Assembler::jmp(Label* label, bool near) { | 1791 void Assembler::jmp(Label* label, bool near) { |
2033 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1792 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2034 if (label->IsBound()) { | 1793 if (label->IsBound()) { |
2035 static const int kShortSize = 2; | 1794 static const int kShortSize = 2; |
2036 static const int kLongSize = 5; | 1795 static const int kLongSize = 5; |
2037 intptr_t offset = label->Position() - buffer_.Size(); | 1796 intptr_t offset = label->Position() - buffer_.Size(); |
2038 ASSERT(offset <= 0); | 1797 ASSERT(offset <= 0); |
2039 if (Utils::IsInt(8, offset - kShortSize)) { | 1798 if (Utils::IsInt(8, offset - kShortSize)) { |
2040 EmitUint8(0xEB); | 1799 EmitUint8(0xEB); |
2041 EmitUint8((offset - kShortSize) & 0xFF); | 1800 EmitUint8((offset - kShortSize) & 0xFF); |
2042 } else { | 1801 } else { |
2043 EmitUint8(0xE9); | 1802 EmitUint8(0xE9); |
2044 EmitInt32(offset - kLongSize); | 1803 EmitInt32(offset - kLongSize); |
2045 } | 1804 } |
2046 } else if (near) { | 1805 } else if (near) { |
2047 EmitUint8(0xEB); | 1806 EmitUint8(0xEB); |
2048 EmitNearLabelLink(label); | 1807 EmitNearLabelLink(label); |
2049 } else { | 1808 } else { |
2050 EmitUint8(0xE9); | 1809 EmitUint8(0xE9); |
2051 EmitLabelLink(label); | 1810 EmitLabelLink(label); |
2052 } | 1811 } |
2053 } | 1812 } |
2054 | 1813 |
2055 | |
2056 void Assembler::jmp(const ExternalLabel* label) { | 1814 void Assembler::jmp(const ExternalLabel* label) { |
2057 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1815 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2058 EmitUint8(0xE9); | 1816 EmitUint8(0xE9); |
2059 EmitFixup(new DirectCallRelocation()); | 1817 EmitFixup(new DirectCallRelocation()); |
2060 EmitInt32(label->address()); | 1818 EmitInt32(label->address()); |
2061 } | 1819 } |
2062 | 1820 |
2063 | |
2064 void Assembler::lock() { | 1821 void Assembler::lock() { |
2065 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1822 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2066 EmitUint8(0xF0); | 1823 EmitUint8(0xF0); |
2067 } | 1824 } |
2068 | 1825 |
2069 | |
2070 void Assembler::cmpxchgl(const Address& address, Register reg) { | 1826 void Assembler::cmpxchgl(const Address& address, Register reg) { |
2071 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1827 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2072 EmitUint8(0x0F); | 1828 EmitUint8(0x0F); |
2073 EmitUint8(0xB1); | 1829 EmitUint8(0xB1); |
2074 EmitOperand(reg, address); | 1830 EmitOperand(reg, address); |
2075 } | 1831 } |
2076 | 1832 |
2077 | |
2078 void Assembler::cpuid() { | 1833 void Assembler::cpuid() { |
2079 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1834 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2080 EmitUint8(0x0F); | 1835 EmitUint8(0x0F); |
2081 EmitUint8(0xA2); | 1836 EmitUint8(0xA2); |
2082 } | 1837 } |
2083 | 1838 |
2084 | |
2085 void Assembler::CompareRegisters(Register a, Register b) { | 1839 void Assembler::CompareRegisters(Register a, Register b) { |
2086 cmpl(a, b); | 1840 cmpl(a, b); |
2087 } | 1841 } |
2088 | 1842 |
2089 | |
2090 void Assembler::MoveRegister(Register to, Register from) { | 1843 void Assembler::MoveRegister(Register to, Register from) { |
2091 if (to != from) { | 1844 if (to != from) { |
2092 movl(to, from); | 1845 movl(to, from); |
2093 } | 1846 } |
2094 } | 1847 } |
2095 | 1848 |
2096 | |
2097 void Assembler::PopRegister(Register r) { | 1849 void Assembler::PopRegister(Register r) { |
2098 popl(r); | 1850 popl(r); |
2099 } | 1851 } |
2100 | 1852 |
2101 | |
2102 void Assembler::AddImmediate(Register reg, const Immediate& imm) { | 1853 void Assembler::AddImmediate(Register reg, const Immediate& imm) { |
2103 const intptr_t value = imm.value(); | 1854 const intptr_t value = imm.value(); |
2104 if (value == 0) { | 1855 if (value == 0) { |
2105 return; | 1856 return; |
2106 } | 1857 } |
2107 if ((value > 0) || (value == kMinInt32)) { | 1858 if ((value > 0) || (value == kMinInt32)) { |
2108 if (value == 1) { | 1859 if (value == 1) { |
2109 incl(reg); | 1860 incl(reg); |
2110 } else { | 1861 } else { |
2111 addl(reg, imm); | 1862 addl(reg, imm); |
2112 } | 1863 } |
2113 } else { | 1864 } else { |
2114 SubImmediate(reg, Immediate(-value)); | 1865 SubImmediate(reg, Immediate(-value)); |
2115 } | 1866 } |
2116 } | 1867 } |
2117 | 1868 |
2118 | |
2119 void Assembler::SubImmediate(Register reg, const Immediate& imm) { | 1869 void Assembler::SubImmediate(Register reg, const Immediate& imm) { |
2120 const intptr_t value = imm.value(); | 1870 const intptr_t value = imm.value(); |
2121 if (value == 0) { | 1871 if (value == 0) { |
2122 return; | 1872 return; |
2123 } | 1873 } |
2124 if ((value > 0) || (value == kMinInt32)) { | 1874 if ((value > 0) || (value == kMinInt32)) { |
2125 if (value == 1) { | 1875 if (value == 1) { |
2126 decl(reg); | 1876 decl(reg); |
2127 } else { | 1877 } else { |
2128 subl(reg, imm); | 1878 subl(reg, imm); |
2129 } | 1879 } |
2130 } else { | 1880 } else { |
2131 AddImmediate(reg, Immediate(-value)); | 1881 AddImmediate(reg, Immediate(-value)); |
2132 } | 1882 } |
2133 } | 1883 } |
2134 | 1884 |
2135 | |
2136 void Assembler::Drop(intptr_t stack_elements) { | 1885 void Assembler::Drop(intptr_t stack_elements) { |
2137 ASSERT(stack_elements >= 0); | 1886 ASSERT(stack_elements >= 0); |
2138 if (stack_elements > 0) { | 1887 if (stack_elements > 0) { |
2139 addl(ESP, Immediate(stack_elements * kWordSize)); | 1888 addl(ESP, Immediate(stack_elements * kWordSize)); |
2140 } | 1889 } |
2141 } | 1890 } |
2142 | 1891 |
2143 | |
2144 void Assembler::LoadIsolate(Register dst) { | 1892 void Assembler::LoadIsolate(Register dst) { |
2145 movl(dst, Address(THR, Thread::isolate_offset())); | 1893 movl(dst, Address(THR, Thread::isolate_offset())); |
2146 } | 1894 } |
2147 | 1895 |
2148 | |
2149 void Assembler::LoadObject(Register dst, const Object& object) { | 1896 void Assembler::LoadObject(Register dst, const Object& object) { |
2150 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); | 1897 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); |
2151 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); | 1898 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); |
2152 if (object.IsSmi() || object.InVMHeap()) { | 1899 if (object.IsSmi() || object.InVMHeap()) { |
2153 movl(dst, Immediate(reinterpret_cast<int32_t>(object.raw()))); | 1900 movl(dst, Immediate(reinterpret_cast<int32_t>(object.raw()))); |
2154 } else { | 1901 } else { |
2155 ASSERT(object.IsNotTemporaryScopedHandle()); | 1902 ASSERT(object.IsNotTemporaryScopedHandle()); |
2156 ASSERT(object.IsOld()); | 1903 ASSERT(object.IsOld()); |
2157 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1904 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2158 EmitUint8(0xB8 + dst); | 1905 EmitUint8(0xB8 + dst); |
2159 buffer_.EmitObject(object); | 1906 buffer_.EmitObject(object); |
2160 } | 1907 } |
2161 } | 1908 } |
2162 | 1909 |
2163 | |
2164 void Assembler::LoadObjectSafely(Register dst, const Object& object) { | 1910 void Assembler::LoadObjectSafely(Register dst, const Object& object) { |
2165 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); | 1911 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); |
2166 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); | 1912 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); |
2167 if (Assembler::IsSafe(object)) { | 1913 if (Assembler::IsSafe(object)) { |
2168 LoadObject(dst, object); | 1914 LoadObject(dst, object); |
2169 } else { | 1915 } else { |
2170 int32_t cookie = jit_cookie(); | 1916 int32_t cookie = jit_cookie(); |
2171 movl(dst, Immediate(reinterpret_cast<int32_t>(object.raw()) ^ cookie)); | 1917 movl(dst, Immediate(reinterpret_cast<int32_t>(object.raw()) ^ cookie)); |
2172 xorl(dst, Immediate(cookie)); | 1918 xorl(dst, Immediate(cookie)); |
2173 } | 1919 } |
2174 } | 1920 } |
2175 | 1921 |
2176 | |
2177 void Assembler::PushObject(const Object& object) { | 1922 void Assembler::PushObject(const Object& object) { |
2178 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); | 1923 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); |
2179 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); | 1924 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); |
2180 if (object.IsSmi() || object.InVMHeap()) { | 1925 if (object.IsSmi() || object.InVMHeap()) { |
2181 pushl(Immediate(reinterpret_cast<int32_t>(object.raw()))); | 1926 pushl(Immediate(reinterpret_cast<int32_t>(object.raw()))); |
2182 } else { | 1927 } else { |
2183 ASSERT(object.IsNotTemporaryScopedHandle()); | 1928 ASSERT(object.IsNotTemporaryScopedHandle()); |
2184 ASSERT(object.IsOld()); | 1929 ASSERT(object.IsOld()); |
2185 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1930 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2186 EmitUint8(0x68); | 1931 EmitUint8(0x68); |
2187 buffer_.EmitObject(object); | 1932 buffer_.EmitObject(object); |
2188 } | 1933 } |
2189 } | 1934 } |
2190 | 1935 |
2191 | |
2192 void Assembler::CompareObject(Register reg, const Object& object) { | 1936 void Assembler::CompareObject(Register reg, const Object& object) { |
2193 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); | 1937 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); |
2194 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); | 1938 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); |
2195 if (object.IsSmi() || object.InVMHeap()) { | 1939 if (object.IsSmi() || object.InVMHeap()) { |
2196 cmpl(reg, Immediate(reinterpret_cast<int32_t>(object.raw()))); | 1940 cmpl(reg, Immediate(reinterpret_cast<int32_t>(object.raw()))); |
2197 } else { | 1941 } else { |
2198 ASSERT(object.IsNotTemporaryScopedHandle()); | 1942 ASSERT(object.IsNotTemporaryScopedHandle()); |
2199 ASSERT(object.IsOld()); | 1943 ASSERT(object.IsOld()); |
2200 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1944 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2201 if (reg == EAX) { | 1945 if (reg == EAX) { |
2202 EmitUint8(0x05 + (7 << 3)); | 1946 EmitUint8(0x05 + (7 << 3)); |
2203 buffer_.EmitObject(object); | 1947 buffer_.EmitObject(object); |
2204 } else { | 1948 } else { |
2205 EmitUint8(0x81); | 1949 EmitUint8(0x81); |
2206 EmitOperand(7, Operand(reg)); | 1950 EmitOperand(7, Operand(reg)); |
2207 buffer_.EmitObject(object); | 1951 buffer_.EmitObject(object); |
2208 } | 1952 } |
2209 } | 1953 } |
2210 } | 1954 } |
2211 | 1955 |
2212 | |
2213 // Destroys the value register. | 1956 // Destroys the value register. |
2214 void Assembler::StoreIntoObjectFilterNoSmi(Register object, | 1957 void Assembler::StoreIntoObjectFilterNoSmi(Register object, |
2215 Register value, | 1958 Register value, |
2216 Label* no_update) { | 1959 Label* no_update) { |
2217 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && | 1960 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && |
2218 (kOldObjectAlignmentOffset == 0)); | 1961 (kOldObjectAlignmentOffset == 0)); |
2219 | 1962 |
2220 // Write-barrier triggers if the value is in the new space (has bit set) and | 1963 // Write-barrier triggers if the value is in the new space (has bit set) and |
2221 // the object is in the old space (has bit cleared). | 1964 // the object is in the old space (has bit cleared). |
2222 // To check that we could compute value & ~object and skip the write barrier | 1965 // To check that we could compute value & ~object and skip the write barrier |
2223 // if the bit is not set. However we can't destroy the object. | 1966 // if the bit is not set. However we can't destroy the object. |
2224 // However to preserve the object we compute negated expression | 1967 // However to preserve the object we compute negated expression |
2225 // ~value | object instead and skip the write barrier if the bit is set. | 1968 // ~value | object instead and skip the write barrier if the bit is set. |
2226 notl(value); | 1969 notl(value); |
2227 orl(value, object); | 1970 orl(value, object); |
2228 testl(value, Immediate(kNewObjectAlignmentOffset)); | 1971 testl(value, Immediate(kNewObjectAlignmentOffset)); |
2229 j(NOT_ZERO, no_update, Assembler::kNearJump); | 1972 j(NOT_ZERO, no_update, Assembler::kNearJump); |
2230 } | 1973 } |
2231 | 1974 |
2232 | |
2233 // Destroys the value register. | 1975 // Destroys the value register. |
2234 void Assembler::StoreIntoObjectFilter(Register object, | 1976 void Assembler::StoreIntoObjectFilter(Register object, |
2235 Register value, | 1977 Register value, |
2236 Label* no_update) { | 1978 Label* no_update) { |
2237 // For the value we are only interested in the new/old bit and the tag bit. | 1979 // For the value we are only interested in the new/old bit and the tag bit. |
2238 andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag)); | 1980 andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag)); |
2239 // Shift the tag bit into the carry. | 1981 // Shift the tag bit into the carry. |
2240 shrl(value, Immediate(1)); | 1982 shrl(value, Immediate(1)); |
2241 // Add the tag bits together, if the value is not a Smi the addition will | 1983 // Add the tag bits together, if the value is not a Smi the addition will |
2242 // overflow into the next bit, leaving us with a zero low bit. | 1984 // overflow into the next bit, leaving us with a zero low bit. |
2243 adcl(value, object); | 1985 adcl(value, object); |
2244 // Mask out higher, uninteresting bits which were polluted by dest. | 1986 // Mask out higher, uninteresting bits which were polluted by dest. |
2245 andl(value, Immediate(kObjectAlignment - 1)); | 1987 andl(value, Immediate(kObjectAlignment - 1)); |
2246 // Compare with the expected bit pattern. | 1988 // Compare with the expected bit pattern. |
2247 cmpl(value, Immediate((kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + | 1989 cmpl(value, Immediate((kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + |
2248 kOldObjectAlignmentOffset + kHeapObjectTag)); | 1990 kOldObjectAlignmentOffset + kHeapObjectTag)); |
2249 j(NOT_ZERO, no_update, Assembler::kNearJump); | 1991 j(NOT_ZERO, no_update, Assembler::kNearJump); |
2250 } | 1992 } |
2251 | 1993 |
2252 | |
2253 // Destroys the value register. | 1994 // Destroys the value register. |
2254 void Assembler::StoreIntoObject(Register object, | 1995 void Assembler::StoreIntoObject(Register object, |
2255 const Address& dest, | 1996 const Address& dest, |
2256 Register value, | 1997 Register value, |
2257 bool can_value_be_smi) { | 1998 bool can_value_be_smi) { |
2258 ASSERT(object != value); | 1999 ASSERT(object != value); |
2259 movl(dest, value); | 2000 movl(dest, value); |
2260 Label done; | 2001 Label done; |
2261 if (can_value_be_smi) { | 2002 if (can_value_be_smi) { |
2262 StoreIntoObjectFilter(object, value, &done); | 2003 StoreIntoObjectFilter(object, value, &done); |
2263 } else { | 2004 } else { |
2264 StoreIntoObjectFilterNoSmi(object, value, &done); | 2005 StoreIntoObjectFilterNoSmi(object, value, &done); |
2265 } | 2006 } |
2266 // A store buffer update is required. | 2007 // A store buffer update is required. |
2267 if (value != EDX) { | 2008 if (value != EDX) { |
2268 pushl(EDX); // Preserve EDX. | 2009 pushl(EDX); // Preserve EDX. |
2269 } | 2010 } |
2270 if (object != EDX) { | 2011 if (object != EDX) { |
2271 movl(EDX, object); | 2012 movl(EDX, object); |
2272 } | 2013 } |
2273 call(Address(THR, Thread::update_store_buffer_entry_point_offset())); | 2014 call(Address(THR, Thread::update_store_buffer_entry_point_offset())); |
2274 if (value != EDX) { | 2015 if (value != EDX) { |
2275 popl(EDX); // Restore EDX. | 2016 popl(EDX); // Restore EDX. |
2276 } | 2017 } |
2277 Bind(&done); | 2018 Bind(&done); |
2278 } | 2019 } |
2279 | 2020 |
2280 | |
2281 void Assembler::StoreIntoObjectNoBarrier(Register object, | 2021 void Assembler::StoreIntoObjectNoBarrier(Register object, |
2282 const Address& dest, | 2022 const Address& dest, |
2283 Register value) { | 2023 Register value) { |
2284 movl(dest, value); | 2024 movl(dest, value); |
2285 #if defined(DEBUG) | 2025 #if defined(DEBUG) |
2286 Label done; | 2026 Label done; |
2287 pushl(value); | 2027 pushl(value); |
2288 StoreIntoObjectFilter(object, value, &done); | 2028 StoreIntoObjectFilter(object, value, &done); |
2289 Stop("Store buffer update is required"); | 2029 Stop("Store buffer update is required"); |
2290 Bind(&done); | 2030 Bind(&done); |
2291 popl(value); | 2031 popl(value); |
2292 #endif // defined(DEBUG) | 2032 #endif // defined(DEBUG) |
2293 // No store buffer update. | 2033 // No store buffer update. |
2294 } | 2034 } |
2295 | 2035 |
2296 | |
2297 void Assembler::UnverifiedStoreOldObject(const Address& dest, | 2036 void Assembler::UnverifiedStoreOldObject(const Address& dest, |
2298 const Object& value) { | 2037 const Object& value) { |
2299 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal()); | 2038 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal()); |
2300 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal()); | 2039 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal()); |
2301 ASSERT(value.IsOld()); | 2040 ASSERT(value.IsOld()); |
2302 ASSERT(!value.InVMHeap()); | 2041 ASSERT(!value.InVMHeap()); |
2303 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2042 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2304 EmitUint8(0xC7); | 2043 EmitUint8(0xC7); |
2305 EmitOperand(0, dest); | 2044 EmitOperand(0, dest); |
2306 buffer_.EmitObject(value); | 2045 buffer_.EmitObject(value); |
2307 } | 2046 } |
2308 | 2047 |
2309 | |
2310 void Assembler::StoreIntoObjectNoBarrier(Register object, | 2048 void Assembler::StoreIntoObjectNoBarrier(Register object, |
2311 const Address& dest, | 2049 const Address& dest, |
2312 const Object& value) { | 2050 const Object& value) { |
2313 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal()); | 2051 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal()); |
2314 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal()); | 2052 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal()); |
2315 if (value.IsSmi() || value.InVMHeap()) { | 2053 if (value.IsSmi() || value.InVMHeap()) { |
2316 Immediate imm_value(reinterpret_cast<int32_t>(value.raw())); | 2054 Immediate imm_value(reinterpret_cast<int32_t>(value.raw())); |
2317 movl(dest, imm_value); | 2055 movl(dest, imm_value); |
2318 } else { | 2056 } else { |
2319 UnverifiedStoreOldObject(dest, value); | 2057 UnverifiedStoreOldObject(dest, value); |
2320 } | 2058 } |
2321 // No store buffer update. | 2059 // No store buffer update. |
2322 } | 2060 } |
2323 | 2061 |
2324 | |
2325 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { | 2062 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { |
2326 #if defined(DEBUG) | 2063 #if defined(DEBUG) |
2327 Label done; | 2064 Label done; |
2328 testl(value, Immediate(kHeapObjectTag)); | 2065 testl(value, Immediate(kHeapObjectTag)); |
2329 j(ZERO, &done); | 2066 j(ZERO, &done); |
2330 Stop("New value must be Smi."); | 2067 Stop("New value must be Smi."); |
2331 Bind(&done); | 2068 Bind(&done); |
2332 #endif // defined(DEBUG) | 2069 #endif // defined(DEBUG) |
2333 movl(dest, value); | 2070 movl(dest, value); |
2334 } | 2071 } |
2335 | 2072 |
2336 | |
2337 void Assembler::ZeroInitSmiField(const Address& dest) { | 2073 void Assembler::ZeroInitSmiField(const Address& dest) { |
2338 Immediate zero(Smi::RawValue(0)); | 2074 Immediate zero(Smi::RawValue(0)); |
2339 movl(dest, zero); | 2075 movl(dest, zero); |
2340 } | 2076 } |
2341 | 2077 |
2342 | |
2343 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) { | 2078 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) { |
2344 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on | 2079 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on |
2345 // the length of this instruction sequence. | 2080 // the length of this instruction sequence. |
2346 Immediate inc_imm(Smi::RawValue(increment)); | 2081 Immediate inc_imm(Smi::RawValue(increment)); |
2347 addl(dest, inc_imm); | 2082 addl(dest, inc_imm); |
2348 } | 2083 } |
2349 | 2084 |
2350 | |
2351 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { | 2085 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { |
2352 // TODO(5410843): Need to have a code constants table. | 2086 // TODO(5410843): Need to have a code constants table. |
2353 int64_t constant = bit_cast<int64_t, double>(value); | 2087 int64_t constant = bit_cast<int64_t, double>(value); |
2354 pushl(Immediate(Utils::High32Bits(constant))); | 2088 pushl(Immediate(Utils::High32Bits(constant))); |
2355 pushl(Immediate(Utils::Low32Bits(constant))); | 2089 pushl(Immediate(Utils::Low32Bits(constant))); |
2356 movsd(dst, Address(ESP, 0)); | 2090 movsd(dst, Address(ESP, 0)); |
2357 addl(ESP, Immediate(2 * kWordSize)); | 2091 addl(ESP, Immediate(2 * kWordSize)); |
2358 } | 2092 } |
2359 | 2093 |
2360 | |
2361 void Assembler::FloatNegate(XmmRegister f) { | 2094 void Assembler::FloatNegate(XmmRegister f) { |
2362 static const struct ALIGN16 { | 2095 static const struct ALIGN16 { |
2363 uint32_t a; | 2096 uint32_t a; |
2364 uint32_t b; | 2097 uint32_t b; |
2365 uint32_t c; | 2098 uint32_t c; |
2366 uint32_t d; | 2099 uint32_t d; |
2367 } float_negate_constant = {0x80000000, 0x00000000, 0x80000000, 0x00000000}; | 2100 } float_negate_constant = {0x80000000, 0x00000000, 0x80000000, 0x00000000}; |
2368 xorps(f, Address::Absolute(reinterpret_cast<uword>(&float_negate_constant))); | 2101 xorps(f, Address::Absolute(reinterpret_cast<uword>(&float_negate_constant))); |
2369 } | 2102 } |
2370 | 2103 |
2371 | |
2372 void Assembler::DoubleNegate(XmmRegister d) { | 2104 void Assembler::DoubleNegate(XmmRegister d) { |
2373 static const struct ALIGN16 { | 2105 static const struct ALIGN16 { |
2374 uint64_t a; | 2106 uint64_t a; |
2375 uint64_t b; | 2107 uint64_t b; |
2376 } double_negate_constant = {0x8000000000000000LL, 0x8000000000000000LL}; | 2108 } double_negate_constant = {0x8000000000000000LL, 0x8000000000000000LL}; |
2377 xorpd(d, Address::Absolute(reinterpret_cast<uword>(&double_negate_constant))); | 2109 xorpd(d, Address::Absolute(reinterpret_cast<uword>(&double_negate_constant))); |
2378 } | 2110 } |
2379 | 2111 |
2380 | |
2381 void Assembler::DoubleAbs(XmmRegister reg) { | 2112 void Assembler::DoubleAbs(XmmRegister reg) { |
2382 static const struct ALIGN16 { | 2113 static const struct ALIGN16 { |
2383 uint64_t a; | 2114 uint64_t a; |
2384 uint64_t b; | 2115 uint64_t b; |
2385 } double_abs_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; | 2116 } double_abs_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; |
2386 andpd(reg, Address::Absolute(reinterpret_cast<uword>(&double_abs_constant))); | 2117 andpd(reg, Address::Absolute(reinterpret_cast<uword>(&double_abs_constant))); |
2387 } | 2118 } |
2388 | 2119 |
2389 | |
2390 void Assembler::EnterFrame(intptr_t frame_size) { | 2120 void Assembler::EnterFrame(intptr_t frame_size) { |
2391 if (prologue_offset_ == -1) { | 2121 if (prologue_offset_ == -1) { |
2392 Comment("PrologueOffset = %" Pd "", CodeSize()); | 2122 Comment("PrologueOffset = %" Pd "", CodeSize()); |
2393 prologue_offset_ = CodeSize(); | 2123 prologue_offset_ = CodeSize(); |
2394 } | 2124 } |
2395 #ifdef DEBUG | 2125 #ifdef DEBUG |
2396 intptr_t check_offset = CodeSize(); | 2126 intptr_t check_offset = CodeSize(); |
2397 #endif | 2127 #endif |
2398 pushl(EBP); | 2128 pushl(EBP); |
2399 movl(EBP, ESP); | 2129 movl(EBP, ESP); |
2400 #ifdef DEBUG | 2130 #ifdef DEBUG |
2401 ProloguePattern pp(CodeAddress(check_offset)); | 2131 ProloguePattern pp(CodeAddress(check_offset)); |
2402 ASSERT(pp.IsValid()); | 2132 ASSERT(pp.IsValid()); |
2403 #endif | 2133 #endif |
2404 if (frame_size != 0) { | 2134 if (frame_size != 0) { |
2405 Immediate frame_space(frame_size); | 2135 Immediate frame_space(frame_size); |
2406 subl(ESP, frame_space); | 2136 subl(ESP, frame_space); |
2407 } | 2137 } |
2408 } | 2138 } |
2409 | 2139 |
2410 | |
2411 void Assembler::LeaveFrame() { | 2140 void Assembler::LeaveFrame() { |
2412 movl(ESP, EBP); | 2141 movl(ESP, EBP); |
2413 popl(EBP); | 2142 popl(EBP); |
2414 } | 2143 } |
2415 | 2144 |
2416 | |
2417 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 2145 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { |
2418 // Reserve space for arguments and align frame before entering | 2146 // Reserve space for arguments and align frame before entering |
2419 // the C++ world. | 2147 // the C++ world. |
2420 AddImmediate(ESP, Immediate(-frame_space)); | 2148 AddImmediate(ESP, Immediate(-frame_space)); |
2421 if (OS::ActivationFrameAlignment() > 1) { | 2149 if (OS::ActivationFrameAlignment() > 1) { |
2422 andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 2150 andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
2423 } | 2151 } |
2424 } | 2152 } |
2425 | 2153 |
2426 | |
2427 static const intptr_t kNumberOfVolatileCpuRegisters = 3; | 2154 static const intptr_t kNumberOfVolatileCpuRegisters = 3; |
2428 static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = { | 2155 static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = { |
2429 EAX, ECX, EDX}; | 2156 EAX, ECX, EDX}; |
2430 | 2157 |
2431 | |
2432 // XMM0 is used only as a scratch register in the optimized code. No need to | 2158 // XMM0 is used only as a scratch register in the optimized code. No need to |
2433 // save it. | 2159 // save it. |
2434 static const intptr_t kNumberOfVolatileXmmRegisters = kNumberOfXmmRegisters - 1; | 2160 static const intptr_t kNumberOfVolatileXmmRegisters = kNumberOfXmmRegisters - 1; |
2435 | 2161 |
2436 | |
2437 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { | 2162 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { |
2438 Comment("EnterCallRuntimeFrame"); | 2163 Comment("EnterCallRuntimeFrame"); |
2439 EnterFrame(0); | 2164 EnterFrame(0); |
2440 | 2165 |
2441 // Preserve volatile CPU registers. | 2166 // Preserve volatile CPU registers. |
2442 for (intptr_t i = 0; i < kNumberOfVolatileCpuRegisters; i++) { | 2167 for (intptr_t i = 0; i < kNumberOfVolatileCpuRegisters; i++) { |
2443 pushl(volatile_cpu_registers[i]); | 2168 pushl(volatile_cpu_registers[i]); |
2444 } | 2169 } |
2445 | 2170 |
2446 // Preserve all XMM registers except XMM0 | 2171 // Preserve all XMM registers except XMM0 |
2447 subl(ESP, Immediate((kNumberOfXmmRegisters - 1) * kFpuRegisterSize)); | 2172 subl(ESP, Immediate((kNumberOfXmmRegisters - 1) * kFpuRegisterSize)); |
2448 // Store XMM registers with the lowest register number at the lowest | 2173 // Store XMM registers with the lowest register number at the lowest |
2449 // address. | 2174 // address. |
2450 intptr_t offset = 0; | 2175 intptr_t offset = 0; |
2451 for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { | 2176 for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { |
2452 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); | 2177 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); |
2453 movups(Address(ESP, offset), xmm_reg); | 2178 movups(Address(ESP, offset), xmm_reg); |
2454 offset += kFpuRegisterSize; | 2179 offset += kFpuRegisterSize; |
2455 } | 2180 } |
2456 | 2181 |
2457 ReserveAlignedFrameSpace(frame_space); | 2182 ReserveAlignedFrameSpace(frame_space); |
2458 } | 2183 } |
2459 | 2184 |
2460 | |
2461 void Assembler::LeaveCallRuntimeFrame() { | 2185 void Assembler::LeaveCallRuntimeFrame() { |
2462 // ESP might have been modified to reserve space for arguments | 2186 // ESP might have been modified to reserve space for arguments |
2463 // and ensure proper alignment of the stack frame. | 2187 // and ensure proper alignment of the stack frame. |
2464 // We need to restore it before restoring registers. | 2188 // We need to restore it before restoring registers. |
2465 const intptr_t kPushedRegistersSize = | 2189 const intptr_t kPushedRegistersSize = |
2466 kNumberOfVolatileCpuRegisters * kWordSize + | 2190 kNumberOfVolatileCpuRegisters * kWordSize + |
2467 kNumberOfVolatileXmmRegisters * kFpuRegisterSize; | 2191 kNumberOfVolatileXmmRegisters * kFpuRegisterSize; |
2468 leal(ESP, Address(EBP, -kPushedRegistersSize)); | 2192 leal(ESP, Address(EBP, -kPushedRegistersSize)); |
2469 | 2193 |
2470 // Restore all XMM registers except XMM0 | 2194 // Restore all XMM registers except XMM0 |
2471 // XMM registers have the lowest register number at the lowest address. | 2195 // XMM registers have the lowest register number at the lowest address. |
2472 intptr_t offset = 0; | 2196 intptr_t offset = 0; |
2473 for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { | 2197 for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { |
2474 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); | 2198 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); |
2475 movups(xmm_reg, Address(ESP, offset)); | 2199 movups(xmm_reg, Address(ESP, offset)); |
2476 offset += kFpuRegisterSize; | 2200 offset += kFpuRegisterSize; |
2477 } | 2201 } |
2478 addl(ESP, Immediate(offset)); | 2202 addl(ESP, Immediate(offset)); |
2479 | 2203 |
2480 // Restore volatile CPU registers. | 2204 // Restore volatile CPU registers. |
2481 for (intptr_t i = kNumberOfVolatileCpuRegisters - 1; i >= 0; i--) { | 2205 for (intptr_t i = kNumberOfVolatileCpuRegisters - 1; i >= 0; i--) { |
2482 popl(volatile_cpu_registers[i]); | 2206 popl(volatile_cpu_registers[i]); |
2483 } | 2207 } |
2484 | 2208 |
2485 leave(); | 2209 leave(); |
2486 } | 2210 } |
2487 | 2211 |
2488 | |
2489 void Assembler::CallRuntime(const RuntimeEntry& entry, | 2212 void Assembler::CallRuntime(const RuntimeEntry& entry, |
2490 intptr_t argument_count) { | 2213 intptr_t argument_count) { |
2491 entry.Call(this, argument_count); | 2214 entry.Call(this, argument_count); |
2492 } | 2215 } |
2493 | 2216 |
2494 | |
2495 void Assembler::Call(const StubEntry& stub_entry) { | 2217 void Assembler::Call(const StubEntry& stub_entry) { |
2496 const Code& target = Code::ZoneHandle(stub_entry.code()); | 2218 const Code& target = Code::ZoneHandle(stub_entry.code()); |
2497 LoadObject(CODE_REG, target); | 2219 LoadObject(CODE_REG, target); |
2498 call(FieldAddress(CODE_REG, Code::entry_point_offset())); | 2220 call(FieldAddress(CODE_REG, Code::entry_point_offset())); |
2499 } | 2221 } |
2500 | 2222 |
2501 | |
2502 void Assembler::CallToRuntime() { | 2223 void Assembler::CallToRuntime() { |
2503 movl(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset())); | 2224 movl(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset())); |
2504 call(Address(THR, Thread::call_to_runtime_entry_point_offset())); | 2225 call(Address(THR, Thread::call_to_runtime_entry_point_offset())); |
2505 } | 2226 } |
2506 | 2227 |
2507 | |
2508 void Assembler::Jmp(const StubEntry& stub_entry) { | 2228 void Assembler::Jmp(const StubEntry& stub_entry) { |
2509 const ExternalLabel label(stub_entry.EntryPoint()); | 2229 const ExternalLabel label(stub_entry.EntryPoint()); |
2510 jmp(&label); | 2230 jmp(&label); |
2511 } | 2231 } |
2512 | 2232 |
2513 | |
2514 void Assembler::J(Condition condition, const StubEntry& stub_entry) { | 2233 void Assembler::J(Condition condition, const StubEntry& stub_entry) { |
2515 const ExternalLabel label(stub_entry.EntryPoint()); | 2234 const ExternalLabel label(stub_entry.EntryPoint()); |
2516 j(condition, &label); | 2235 j(condition, &label); |
2517 } | 2236 } |
2518 | 2237 |
2519 | |
2520 void Assembler::Align(intptr_t alignment, intptr_t offset) { | 2238 void Assembler::Align(intptr_t alignment, intptr_t offset) { |
2521 ASSERT(Utils::IsPowerOfTwo(alignment)); | 2239 ASSERT(Utils::IsPowerOfTwo(alignment)); |
2522 intptr_t pos = offset + buffer_.GetPosition(); | 2240 intptr_t pos = offset + buffer_.GetPosition(); |
2523 intptr_t mod = pos & (alignment - 1); | 2241 intptr_t mod = pos & (alignment - 1); |
2524 if (mod == 0) { | 2242 if (mod == 0) { |
2525 return; | 2243 return; |
2526 } | 2244 } |
2527 intptr_t bytes_needed = alignment - mod; | 2245 intptr_t bytes_needed = alignment - mod; |
2528 while (bytes_needed > MAX_NOP_SIZE) { | 2246 while (bytes_needed > MAX_NOP_SIZE) { |
2529 nop(MAX_NOP_SIZE); | 2247 nop(MAX_NOP_SIZE); |
2530 bytes_needed -= MAX_NOP_SIZE; | 2248 bytes_needed -= MAX_NOP_SIZE; |
2531 } | 2249 } |
2532 if (bytes_needed) { | 2250 if (bytes_needed) { |
2533 nop(bytes_needed); | 2251 nop(bytes_needed); |
2534 } | 2252 } |
2535 ASSERT(((offset + buffer_.GetPosition()) & (alignment - 1)) == 0); | 2253 ASSERT(((offset + buffer_.GetPosition()) & (alignment - 1)) == 0); |
2536 } | 2254 } |
2537 | 2255 |
2538 | |
2539 void Assembler::Bind(Label* label) { | 2256 void Assembler::Bind(Label* label) { |
2540 intptr_t bound = buffer_.Size(); | 2257 intptr_t bound = buffer_.Size(); |
2541 ASSERT(!label->IsBound()); // Labels can only be bound once. | 2258 ASSERT(!label->IsBound()); // Labels can only be bound once. |
2542 while (label->IsLinked()) { | 2259 while (label->IsLinked()) { |
2543 intptr_t position = label->LinkPosition(); | 2260 intptr_t position = label->LinkPosition(); |
2544 intptr_t next = buffer_.Load<int32_t>(position); | 2261 intptr_t next = buffer_.Load<int32_t>(position); |
2545 buffer_.Store<int32_t>(position, bound - (position + 4)); | 2262 buffer_.Store<int32_t>(position, bound - (position + 4)); |
2546 label->position_ = next; | 2263 label->position_ = next; |
2547 } | 2264 } |
2548 while (label->HasNear()) { | 2265 while (label->HasNear()) { |
2549 intptr_t position = label->NearPosition(); | 2266 intptr_t position = label->NearPosition(); |
2550 intptr_t offset = bound - (position + 1); | 2267 intptr_t offset = bound - (position + 1); |
2551 ASSERT(Utils::IsInt(8, offset)); | 2268 ASSERT(Utils::IsInt(8, offset)); |
2552 buffer_.Store<int8_t>(position, offset); | 2269 buffer_.Store<int8_t>(position, offset); |
2553 } | 2270 } |
2554 label->BindTo(bound); | 2271 label->BindTo(bound); |
2555 } | 2272 } |
2556 | 2273 |
2557 | |
2558 #ifndef PRODUCT | 2274 #ifndef PRODUCT |
2559 void Assembler::MaybeTraceAllocation(intptr_t cid, | 2275 void Assembler::MaybeTraceAllocation(intptr_t cid, |
2560 Register temp_reg, | 2276 Register temp_reg, |
2561 Label* trace, | 2277 Label* trace, |
2562 bool near_jump) { | 2278 bool near_jump) { |
2563 ASSERT(cid > 0); | 2279 ASSERT(cid > 0); |
2564 Address state_address(kNoRegister, 0); | 2280 Address state_address(kNoRegister, 0); |
2565 intptr_t state_offset = ClassTable::StateOffsetFor(cid); | 2281 intptr_t state_offset = ClassTable::StateOffsetFor(cid); |
2566 ASSERT(temp_reg != kNoRegister); | 2282 ASSERT(temp_reg != kNoRegister); |
2567 LoadIsolate(temp_reg); | 2283 LoadIsolate(temp_reg); |
2568 intptr_t table_offset = | 2284 intptr_t table_offset = |
2569 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); | 2285 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); |
2570 movl(temp_reg, Address(temp_reg, table_offset)); | 2286 movl(temp_reg, Address(temp_reg, table_offset)); |
2571 state_address = Address(temp_reg, state_offset); | 2287 state_address = Address(temp_reg, state_offset); |
2572 testb(state_address, Immediate(ClassHeapStats::TraceAllocationMask())); | 2288 testb(state_address, Immediate(ClassHeapStats::TraceAllocationMask())); |
2573 // We are tracing for this class, jump to the trace label which will use | 2289 // We are tracing for this class, jump to the trace label which will use |
2574 // the allocation stub. | 2290 // the allocation stub. |
2575 j(NOT_ZERO, trace, near_jump); | 2291 j(NOT_ZERO, trace, near_jump); |
2576 } | 2292 } |
2577 | 2293 |
2578 | |
2579 void Assembler::UpdateAllocationStats(intptr_t cid, | 2294 void Assembler::UpdateAllocationStats(intptr_t cid, |
2580 Register temp_reg, | 2295 Register temp_reg, |
2581 Heap::Space space) { | 2296 Heap::Space space) { |
2582 ASSERT(cid > 0); | 2297 ASSERT(cid > 0); |
2583 intptr_t counter_offset = | 2298 intptr_t counter_offset = |
2584 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); | 2299 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); |
2585 ASSERT(temp_reg != kNoRegister); | 2300 ASSERT(temp_reg != kNoRegister); |
2586 LoadIsolate(temp_reg); | 2301 LoadIsolate(temp_reg); |
2587 intptr_t table_offset = | 2302 intptr_t table_offset = |
2588 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); | 2303 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); |
2589 movl(temp_reg, Address(temp_reg, table_offset)); | 2304 movl(temp_reg, Address(temp_reg, table_offset)); |
2590 incl(Address(temp_reg, counter_offset)); | 2305 incl(Address(temp_reg, counter_offset)); |
2591 } | 2306 } |
2592 | 2307 |
2593 | |
2594 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, | 2308 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, |
2595 Register size_reg, | 2309 Register size_reg, |
2596 Register temp_reg, | 2310 Register temp_reg, |
2597 Heap::Space space) { | 2311 Heap::Space space) { |
2598 ASSERT(cid > 0); | 2312 ASSERT(cid > 0); |
2599 ASSERT(cid < kNumPredefinedCids); | 2313 ASSERT(cid < kNumPredefinedCids); |
2600 UpdateAllocationStats(cid, temp_reg, space); | 2314 UpdateAllocationStats(cid, temp_reg, space); |
2601 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); | 2315 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); |
2602 addl(Address(temp_reg, size_offset), size_reg); | 2316 addl(Address(temp_reg, size_offset), size_reg); |
2603 } | 2317 } |
2604 | 2318 |
2605 | |
2606 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, | 2319 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, |
2607 intptr_t size_in_bytes, | 2320 intptr_t size_in_bytes, |
2608 Register temp_reg, | 2321 Register temp_reg, |
2609 Heap::Space space) { | 2322 Heap::Space space) { |
2610 ASSERT(cid > 0); | 2323 ASSERT(cid > 0); |
2611 ASSERT(cid < kNumPredefinedCids); | 2324 ASSERT(cid < kNumPredefinedCids); |
2612 UpdateAllocationStats(cid, temp_reg, space); | 2325 UpdateAllocationStats(cid, temp_reg, space); |
2613 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); | 2326 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); |
2614 addl(Address(temp_reg, size_offset), Immediate(size_in_bytes)); | 2327 addl(Address(temp_reg, size_offset), Immediate(size_in_bytes)); |
2615 } | 2328 } |
2616 #endif // !PRODUCT | 2329 #endif // !PRODUCT |
2617 | 2330 |
2618 | |
2619 void Assembler::TryAllocate(const Class& cls, | 2331 void Assembler::TryAllocate(const Class& cls, |
2620 Label* failure, | 2332 Label* failure, |
2621 bool near_jump, | 2333 bool near_jump, |
2622 Register instance_reg, | 2334 Register instance_reg, |
2623 Register temp_reg) { | 2335 Register temp_reg) { |
2624 ASSERT(failure != NULL); | 2336 ASSERT(failure != NULL); |
2625 ASSERT(temp_reg != kNoRegister); | 2337 ASSERT(temp_reg != kNoRegister); |
2626 if (FLAG_inline_alloc) { | 2338 if (FLAG_inline_alloc) { |
2627 // If this allocation is traced, program will jump to failure path | 2339 // If this allocation is traced, program will jump to failure path |
2628 // (i.e. the allocation stub) which will allocate the object and trace the | 2340 // (i.e. the allocation stub) which will allocate the object and trace the |
(...skipping 17 matching lines...) Expand all Loading... |
2646 uint32_t tags = 0; | 2358 uint32_t tags = 0; |
2647 tags = RawObject::SizeTag::update(instance_size, tags); | 2359 tags = RawObject::SizeTag::update(instance_size, tags); |
2648 ASSERT(cls.id() != kIllegalCid); | 2360 ASSERT(cls.id() != kIllegalCid); |
2649 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 2361 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
2650 movl(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags)); | 2362 movl(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags)); |
2651 } else { | 2363 } else { |
2652 jmp(failure); | 2364 jmp(failure); |
2653 } | 2365 } |
2654 } | 2366 } |
2655 | 2367 |
2656 | |
2657 void Assembler::TryAllocateArray(intptr_t cid, | 2368 void Assembler::TryAllocateArray(intptr_t cid, |
2658 intptr_t instance_size, | 2369 intptr_t instance_size, |
2659 Label* failure, | 2370 Label* failure, |
2660 bool near_jump, | 2371 bool near_jump, |
2661 Register instance, | 2372 Register instance, |
2662 Register end_address, | 2373 Register end_address, |
2663 Register temp_reg) { | 2374 Register temp_reg) { |
2664 ASSERT(failure != NULL); | 2375 ASSERT(failure != NULL); |
2665 ASSERT(temp_reg != kNoRegister); | 2376 ASSERT(temp_reg != kNoRegister); |
2666 if (FLAG_inline_alloc) { | 2377 if (FLAG_inline_alloc) { |
(...skipping 25 matching lines...) Expand all Loading... |
2692 // Initialize the tags. | 2403 // Initialize the tags. |
2693 uint32_t tags = 0; | 2404 uint32_t tags = 0; |
2694 tags = RawObject::ClassIdTag::update(cid, tags); | 2405 tags = RawObject::ClassIdTag::update(cid, tags); |
2695 tags = RawObject::SizeTag::update(instance_size, tags); | 2406 tags = RawObject::SizeTag::update(instance_size, tags); |
2696 movl(FieldAddress(instance, Object::tags_offset()), Immediate(tags)); | 2407 movl(FieldAddress(instance, Object::tags_offset()), Immediate(tags)); |
2697 } else { | 2408 } else { |
2698 jmp(failure); | 2409 jmp(failure); |
2699 } | 2410 } |
2700 } | 2411 } |
2701 | 2412 |
2702 | |
2703 void Assembler::PushCodeObject() { | 2413 void Assembler::PushCodeObject() { |
2704 ASSERT(code_.IsNotTemporaryScopedHandle()); | 2414 ASSERT(code_.IsNotTemporaryScopedHandle()); |
2705 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2415 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2706 EmitUint8(0x68); | 2416 EmitUint8(0x68); |
2707 buffer_.EmitObject(code_); | 2417 buffer_.EmitObject(code_); |
2708 } | 2418 } |
2709 | 2419 |
2710 | |
2711 void Assembler::EnterDartFrame(intptr_t frame_size) { | 2420 void Assembler::EnterDartFrame(intptr_t frame_size) { |
2712 EnterFrame(0); | 2421 EnterFrame(0); |
2713 | 2422 |
2714 PushCodeObject(); | 2423 PushCodeObject(); |
2715 | 2424 |
2716 if (frame_size != 0) { | 2425 if (frame_size != 0) { |
2717 subl(ESP, Immediate(frame_size)); | 2426 subl(ESP, Immediate(frame_size)); |
2718 } | 2427 } |
2719 } | 2428 } |
2720 | 2429 |
2721 | |
2722 // On entry to a function compiled for OSR, the caller's frame pointer, the | 2430 // On entry to a function compiled for OSR, the caller's frame pointer, the |
2723 // stack locals, and any copied parameters are already in place. The frame | 2431 // stack locals, and any copied parameters are already in place. The frame |
2724 // pointer is already set up. There may be extra space for spill slots to | 2432 // pointer is already set up. There may be extra space for spill slots to |
2725 // allocate. | 2433 // allocate. |
2726 void Assembler::EnterOsrFrame(intptr_t extra_size) { | 2434 void Assembler::EnterOsrFrame(intptr_t extra_size) { |
2727 Comment("EnterOsrFrame"); | 2435 Comment("EnterOsrFrame"); |
2728 if (prologue_offset_ == -1) { | 2436 if (prologue_offset_ == -1) { |
2729 Comment("PrologueOffset = %" Pd "", CodeSize()); | 2437 Comment("PrologueOffset = %" Pd "", CodeSize()); |
2730 prologue_offset_ = CodeSize(); | 2438 prologue_offset_ = CodeSize(); |
2731 } | 2439 } |
2732 | 2440 |
2733 if (extra_size != 0) { | 2441 if (extra_size != 0) { |
2734 subl(ESP, Immediate(extra_size)); | 2442 subl(ESP, Immediate(extra_size)); |
2735 } | 2443 } |
2736 } | 2444 } |
2737 | 2445 |
2738 | |
2739 void Assembler::EnterStubFrame() { | 2446 void Assembler::EnterStubFrame() { |
2740 EnterDartFrame(0); | 2447 EnterDartFrame(0); |
2741 } | 2448 } |
2742 | 2449 |
2743 | |
2744 void Assembler::Stop(const char* message) { | 2450 void Assembler::Stop(const char* message) { |
2745 if (FLAG_print_stop_message) { | 2451 if (FLAG_print_stop_message) { |
2746 pushl(EAX); // Preserve EAX. | 2452 pushl(EAX); // Preserve EAX. |
2747 movl(EAX, Immediate(reinterpret_cast<int32_t>(message))); | 2453 movl(EAX, Immediate(reinterpret_cast<int32_t>(message))); |
2748 Call(*StubCode::PrintStopMessage_entry()); // Passing message in EAX. | 2454 Call(*StubCode::PrintStopMessage_entry()); // Passing message in EAX. |
2749 popl(EAX); // Restore EAX. | 2455 popl(EAX); // Restore EAX. |
2750 } else { | 2456 } else { |
2751 // Emit the message address as immediate operand in the test instruction. | 2457 // Emit the message address as immediate operand in the test instruction. |
2752 testl(EAX, Immediate(reinterpret_cast<int32_t>(message))); | 2458 testl(EAX, Immediate(reinterpret_cast<int32_t>(message))); |
2753 } | 2459 } |
2754 // Emit the int3 instruction. | 2460 // Emit the int3 instruction. |
2755 int3(); // Execution can be resumed with the 'cont' command in gdb. | 2461 int3(); // Execution can be resumed with the 'cont' command in gdb. |
2756 } | 2462 } |
2757 | 2463 |
2758 | |
2759 void Assembler::EmitOperand(int rm, const Operand& operand) { | 2464 void Assembler::EmitOperand(int rm, const Operand& operand) { |
2760 ASSERT(rm >= 0 && rm < 8); | 2465 ASSERT(rm >= 0 && rm < 8); |
2761 const intptr_t length = operand.length_; | 2466 const intptr_t length = operand.length_; |
2762 ASSERT(length > 0); | 2467 ASSERT(length > 0); |
2763 // Emit the ModRM byte updated with the given RM value. | 2468 // Emit the ModRM byte updated with the given RM value. |
2764 ASSERT((operand.encoding_[0] & 0x38) == 0); | 2469 ASSERT((operand.encoding_[0] & 0x38) == 0); |
2765 EmitUint8(operand.encoding_[0] + (rm << 3)); | 2470 EmitUint8(operand.encoding_[0] + (rm << 3)); |
2766 // Emit the rest of the encoded operand. | 2471 // Emit the rest of the encoded operand. |
2767 for (intptr_t i = 1; i < length; i++) { | 2472 for (intptr_t i = 1; i < length; i++) { |
2768 EmitUint8(operand.encoding_[i]); | 2473 EmitUint8(operand.encoding_[i]); |
2769 } | 2474 } |
2770 } | 2475 } |
2771 | 2476 |
2772 | |
2773 void Assembler::EmitImmediate(const Immediate& imm) { | 2477 void Assembler::EmitImmediate(const Immediate& imm) { |
2774 EmitInt32(imm.value()); | 2478 EmitInt32(imm.value()); |
2775 } | 2479 } |
2776 | 2480 |
2777 | |
2778 void Assembler::EmitComplex(int rm, | 2481 void Assembler::EmitComplex(int rm, |
2779 const Operand& operand, | 2482 const Operand& operand, |
2780 const Immediate& immediate) { | 2483 const Immediate& immediate) { |
2781 ASSERT(rm >= 0 && rm < 8); | 2484 ASSERT(rm >= 0 && rm < 8); |
2782 if (immediate.is_int8()) { | 2485 if (immediate.is_int8()) { |
2783 // Use sign-extended 8-bit immediate. | 2486 // Use sign-extended 8-bit immediate. |
2784 EmitUint8(0x83); | 2487 EmitUint8(0x83); |
2785 EmitOperand(rm, operand); | 2488 EmitOperand(rm, operand); |
2786 EmitUint8(immediate.value() & 0xFF); | 2489 EmitUint8(immediate.value() & 0xFF); |
2787 } else if (operand.IsRegister(EAX)) { | 2490 } else if (operand.IsRegister(EAX)) { |
2788 // Use short form if the destination is eax. | 2491 // Use short form if the destination is eax. |
2789 EmitUint8(0x05 + (rm << 3)); | 2492 EmitUint8(0x05 + (rm << 3)); |
2790 EmitImmediate(immediate); | 2493 EmitImmediate(immediate); |
2791 } else { | 2494 } else { |
2792 EmitUint8(0x81); | 2495 EmitUint8(0x81); |
2793 EmitOperand(rm, operand); | 2496 EmitOperand(rm, operand); |
2794 EmitImmediate(immediate); | 2497 EmitImmediate(immediate); |
2795 } | 2498 } |
2796 } | 2499 } |
2797 | 2500 |
2798 | |
2799 void Assembler::EmitLabel(Label* label, intptr_t instruction_size) { | 2501 void Assembler::EmitLabel(Label* label, intptr_t instruction_size) { |
2800 if (label->IsBound()) { | 2502 if (label->IsBound()) { |
2801 intptr_t offset = label->Position() - buffer_.Size(); | 2503 intptr_t offset = label->Position() - buffer_.Size(); |
2802 ASSERT(offset <= 0); | 2504 ASSERT(offset <= 0); |
2803 EmitInt32(offset - instruction_size); | 2505 EmitInt32(offset - instruction_size); |
2804 } else { | 2506 } else { |
2805 EmitLabelLink(label); | 2507 EmitLabelLink(label); |
2806 } | 2508 } |
2807 } | 2509 } |
2808 | 2510 |
2809 | |
2810 void Assembler::EmitLabelLink(Label* label) { | 2511 void Assembler::EmitLabelLink(Label* label) { |
2811 ASSERT(!label->IsBound()); | 2512 ASSERT(!label->IsBound()); |
2812 intptr_t position = buffer_.Size(); | 2513 intptr_t position = buffer_.Size(); |
2813 EmitInt32(label->position_); | 2514 EmitInt32(label->position_); |
2814 label->LinkTo(position); | 2515 label->LinkTo(position); |
2815 } | 2516 } |
2816 | 2517 |
2817 | |
2818 void Assembler::EmitNearLabelLink(Label* label) { | 2518 void Assembler::EmitNearLabelLink(Label* label) { |
2819 ASSERT(!label->IsBound()); | 2519 ASSERT(!label->IsBound()); |
2820 intptr_t position = buffer_.Size(); | 2520 intptr_t position = buffer_.Size(); |
2821 EmitUint8(0); | 2521 EmitUint8(0); |
2822 label->NearLinkTo(position); | 2522 label->NearLinkTo(position); |
2823 } | 2523 } |
2824 | 2524 |
2825 | |
2826 void Assembler::EmitGenericShift(int rm, Register reg, const Immediate& imm) { | 2525 void Assembler::EmitGenericShift(int rm, Register reg, const Immediate& imm) { |
2827 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2526 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2828 ASSERT(imm.is_int8()); | 2527 ASSERT(imm.is_int8()); |
2829 if (imm.value() == 1) { | 2528 if (imm.value() == 1) { |
2830 EmitUint8(0xD1); | 2529 EmitUint8(0xD1); |
2831 EmitOperand(rm, Operand(reg)); | 2530 EmitOperand(rm, Operand(reg)); |
2832 } else { | 2531 } else { |
2833 EmitUint8(0xC1); | 2532 EmitUint8(0xC1); |
2834 EmitOperand(rm, Operand(reg)); | 2533 EmitOperand(rm, Operand(reg)); |
2835 EmitUint8(imm.value() & 0xFF); | 2534 EmitUint8(imm.value() & 0xFF); |
2836 } | 2535 } |
2837 } | 2536 } |
2838 | 2537 |
2839 | |
2840 void Assembler::EmitGenericShift(int rm, | 2538 void Assembler::EmitGenericShift(int rm, |
2841 const Operand& operand, | 2539 const Operand& operand, |
2842 Register shifter) { | 2540 Register shifter) { |
2843 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2541 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2844 ASSERT(shifter == ECX); | 2542 ASSERT(shifter == ECX); |
2845 EmitUint8(0xD3); | 2543 EmitUint8(0xD3); |
2846 EmitOperand(rm, Operand(operand)); | 2544 EmitOperand(rm, Operand(operand)); |
2847 } | 2545 } |
2848 | 2546 |
2849 | |
2850 void Assembler::LoadClassId(Register result, Register object) { | 2547 void Assembler::LoadClassId(Register result, Register object) { |
2851 ASSERT(RawObject::kClassIdTagPos == 16); | 2548 ASSERT(RawObject::kClassIdTagPos == 16); |
2852 ASSERT(RawObject::kClassIdTagSize == 16); | 2549 ASSERT(RawObject::kClassIdTagSize == 16); |
2853 const intptr_t class_id_offset = | 2550 const intptr_t class_id_offset = |
2854 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte; | 2551 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte; |
2855 movzxw(result, FieldAddress(object, class_id_offset)); | 2552 movzxw(result, FieldAddress(object, class_id_offset)); |
2856 } | 2553 } |
2857 | 2554 |
2858 | |
2859 void Assembler::LoadClassById(Register result, Register class_id) { | 2555 void Assembler::LoadClassById(Register result, Register class_id) { |
2860 ASSERT(result != class_id); | 2556 ASSERT(result != class_id); |
2861 LoadIsolate(result); | 2557 LoadIsolate(result); |
2862 const intptr_t offset = | 2558 const intptr_t offset = |
2863 Isolate::class_table_offset() + ClassTable::table_offset(); | 2559 Isolate::class_table_offset() + ClassTable::table_offset(); |
2864 movl(result, Address(result, offset)); | 2560 movl(result, Address(result, offset)); |
2865 movl(result, Address(result, class_id, TIMES_4, 0)); | 2561 movl(result, Address(result, class_id, TIMES_4, 0)); |
2866 } | 2562 } |
2867 | 2563 |
2868 | |
2869 void Assembler::LoadClass(Register result, Register object, Register scratch) { | 2564 void Assembler::LoadClass(Register result, Register object, Register scratch) { |
2870 ASSERT(scratch != result); | 2565 ASSERT(scratch != result); |
2871 LoadClassId(scratch, object); | 2566 LoadClassId(scratch, object); |
2872 LoadClassById(result, scratch); | 2567 LoadClassById(result, scratch); |
2873 } | 2568 } |
2874 | 2569 |
2875 | |
2876 void Assembler::CompareClassId(Register object, | 2570 void Assembler::CompareClassId(Register object, |
2877 intptr_t class_id, | 2571 intptr_t class_id, |
2878 Register scratch) { | 2572 Register scratch) { |
2879 LoadClassId(scratch, object); | 2573 LoadClassId(scratch, object); |
2880 cmpl(scratch, Immediate(class_id)); | 2574 cmpl(scratch, Immediate(class_id)); |
2881 } | 2575 } |
2882 | 2576 |
2883 | |
2884 void Assembler::SmiUntagOrCheckClass(Register object, | 2577 void Assembler::SmiUntagOrCheckClass(Register object, |
2885 intptr_t class_id, | 2578 intptr_t class_id, |
2886 Register scratch, | 2579 Register scratch, |
2887 Label* is_smi) { | 2580 Label* is_smi) { |
2888 ASSERT(kSmiTagShift == 1); | 2581 ASSERT(kSmiTagShift == 1); |
2889 ASSERT(RawObject::kClassIdTagPos == 16); | 2582 ASSERT(RawObject::kClassIdTagPos == 16); |
2890 ASSERT(RawObject::kClassIdTagSize == 16); | 2583 ASSERT(RawObject::kClassIdTagSize == 16); |
2891 const intptr_t class_id_offset = | 2584 const intptr_t class_id_offset = |
2892 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte; | 2585 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte; |
2893 | 2586 |
2894 // Untag optimistically. Tag bit is shifted into the CARRY. | 2587 // Untag optimistically. Tag bit is shifted into the CARRY. |
2895 SmiUntag(object); | 2588 SmiUntag(object); |
2896 j(NOT_CARRY, is_smi, kNearJump); | 2589 j(NOT_CARRY, is_smi, kNearJump); |
2897 // Load cid: can't use LoadClassId, object is untagged. Use TIMES_2 scale | 2590 // Load cid: can't use LoadClassId, object is untagged. Use TIMES_2 scale |
2898 // factor in the addressing mode to compensate for this. | 2591 // factor in the addressing mode to compensate for this. |
2899 movzxw(scratch, Address(object, TIMES_2, class_id_offset)); | 2592 movzxw(scratch, Address(object, TIMES_2, class_id_offset)); |
2900 cmpl(scratch, Immediate(class_id)); | 2593 cmpl(scratch, Immediate(class_id)); |
2901 } | 2594 } |
2902 | 2595 |
2903 | |
2904 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) { | 2596 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) { |
2905 if (result == object) { | 2597 if (result == object) { |
2906 Label smi, join; | 2598 Label smi, join; |
2907 | 2599 |
2908 testl(object, Immediate(kSmiTagMask)); | 2600 testl(object, Immediate(kSmiTagMask)); |
2909 j(EQUAL, &smi, Assembler::kNearJump); | 2601 j(EQUAL, &smi, Assembler::kNearJump); |
2910 LoadClassId(result, object); | 2602 LoadClassId(result, object); |
2911 jmp(&join, Assembler::kNearJump); | 2603 jmp(&join, Assembler::kNearJump); |
2912 | 2604 |
2913 Bind(&smi); | 2605 Bind(&smi); |
(...skipping 10 matching lines...) Expand all Loading... |
2924 // Check if object (in tmp) is a Smi. | 2616 // Check if object (in tmp) is a Smi. |
2925 testl(object, Immediate(kSmiTagMask)); | 2617 testl(object, Immediate(kSmiTagMask)); |
2926 | 2618 |
2927 // If the object is not a Smi, use the original object to load the cid. | 2619 // If the object is not a Smi, use the original object to load the cid. |
2928 // Otherwise, the dummy object is used, and the result is kSmiCid. | 2620 // Otherwise, the dummy object is used, and the result is kSmiCid. |
2929 cmovne(result, object); | 2621 cmovne(result, object); |
2930 LoadClassId(result, result); | 2622 LoadClassId(result, result); |
2931 } | 2623 } |
2932 } | 2624 } |
2933 | 2625 |
2934 | |
2935 void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) { | 2626 void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) { |
2936 if (result == object) { | 2627 if (result == object) { |
2937 Label smi, join; | 2628 Label smi, join; |
2938 | 2629 |
2939 testl(object, Immediate(kSmiTagMask)); | 2630 testl(object, Immediate(kSmiTagMask)); |
2940 j(EQUAL, &smi, Assembler::kNearJump); | 2631 j(EQUAL, &smi, Assembler::kNearJump); |
2941 LoadClassId(result, object); | 2632 LoadClassId(result, object); |
2942 SmiTag(result); | 2633 SmiTag(result); |
2943 jmp(&join, Assembler::kNearJump); | 2634 jmp(&join, Assembler::kNearJump); |
2944 | 2635 |
2945 Bind(&smi); | 2636 Bind(&smi); |
2946 movl(result, Immediate(Smi::RawValue(kSmiCid))); | 2637 movl(result, Immediate(Smi::RawValue(kSmiCid))); |
2947 | 2638 |
2948 Bind(&join); | 2639 Bind(&join); |
2949 } else { | 2640 } else { |
2950 LoadClassIdMayBeSmi(result, object); | 2641 LoadClassIdMayBeSmi(result, object); |
2951 SmiTag(result); | 2642 SmiTag(result); |
2952 } | 2643 } |
2953 } | 2644 } |
2954 | 2645 |
2955 | |
2956 Address Assembler::ElementAddressForIntIndex(bool is_external, | 2646 Address Assembler::ElementAddressForIntIndex(bool is_external, |
2957 intptr_t cid, | 2647 intptr_t cid, |
2958 intptr_t index_scale, | 2648 intptr_t index_scale, |
2959 Register array, | 2649 Register array, |
2960 intptr_t index) { | 2650 intptr_t index) { |
2961 if (is_external) { | 2651 if (is_external) { |
2962 return Address(array, index * index_scale); | 2652 return Address(array, index * index_scale); |
2963 } else { | 2653 } else { |
2964 const int64_t disp = static_cast<int64_t>(index) * index_scale + | 2654 const int64_t disp = static_cast<int64_t>(index) * index_scale + |
2965 Instance::DataOffsetFor(cid); | 2655 Instance::DataOffsetFor(cid); |
2966 ASSERT(Utils::IsInt(32, disp)); | 2656 ASSERT(Utils::IsInt(32, disp)); |
2967 return FieldAddress(array, static_cast<int32_t>(disp)); | 2657 return FieldAddress(array, static_cast<int32_t>(disp)); |
2968 } | 2658 } |
2969 } | 2659 } |
2970 | 2660 |
2971 | |
2972 static ScaleFactor ToScaleFactor(intptr_t index_scale) { | 2661 static ScaleFactor ToScaleFactor(intptr_t index_scale) { |
2973 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with | 2662 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with |
2974 // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is | 2663 // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is |
2975 // expected to be untagged before accessing. | 2664 // expected to be untagged before accessing. |
2976 ASSERT(kSmiTagShift == 1); | 2665 ASSERT(kSmiTagShift == 1); |
2977 switch (index_scale) { | 2666 switch (index_scale) { |
2978 case 1: | 2667 case 1: |
2979 return TIMES_1; | 2668 return TIMES_1; |
2980 case 2: | 2669 case 2: |
2981 return TIMES_1; | 2670 return TIMES_1; |
2982 case 4: | 2671 case 4: |
2983 return TIMES_2; | 2672 return TIMES_2; |
2984 case 8: | 2673 case 8: |
2985 return TIMES_4; | 2674 return TIMES_4; |
2986 case 16: | 2675 case 16: |
2987 return TIMES_8; | 2676 return TIMES_8; |
2988 default: | 2677 default: |
2989 UNREACHABLE(); | 2678 UNREACHABLE(); |
2990 return TIMES_1; | 2679 return TIMES_1; |
2991 } | 2680 } |
2992 } | 2681 } |
2993 | 2682 |
2994 | |
2995 Address Assembler::ElementAddressForRegIndex(bool is_external, | 2683 Address Assembler::ElementAddressForRegIndex(bool is_external, |
2996 intptr_t cid, | 2684 intptr_t cid, |
2997 intptr_t index_scale, | 2685 intptr_t index_scale, |
2998 Register array, | 2686 Register array, |
2999 Register index) { | 2687 Register index) { |
3000 if (is_external) { | 2688 if (is_external) { |
3001 return Address(array, index, ToScaleFactor(index_scale), 0); | 2689 return Address(array, index, ToScaleFactor(index_scale), 0); |
3002 } else { | 2690 } else { |
3003 return FieldAddress(array, index, ToScaleFactor(index_scale), | 2691 return FieldAddress(array, index, ToScaleFactor(index_scale), |
3004 Instance::DataOffsetFor(cid)); | 2692 Instance::DataOffsetFor(cid)); |
3005 } | 2693 } |
3006 } | 2694 } |
3007 | 2695 |
3008 | |
3009 static const char* cpu_reg_names[kNumberOfCpuRegisters] = { | 2696 static const char* cpu_reg_names[kNumberOfCpuRegisters] = { |
3010 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; | 2697 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; |
3011 | 2698 |
3012 | |
3013 const char* Assembler::RegisterName(Register reg) { | 2699 const char* Assembler::RegisterName(Register reg) { |
3014 ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters)); | 2700 ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters)); |
3015 return cpu_reg_names[reg]; | 2701 return cpu_reg_names[reg]; |
3016 } | 2702 } |
3017 | 2703 |
3018 | |
3019 static const char* xmm_reg_names[kNumberOfXmmRegisters] = { | 2704 static const char* xmm_reg_names[kNumberOfXmmRegisters] = { |
3020 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"}; | 2705 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"}; |
3021 | 2706 |
3022 | |
3023 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2707 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
3024 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 2708 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
3025 return xmm_reg_names[reg]; | 2709 return xmm_reg_names[reg]; |
3026 } | 2710 } |
3027 | 2711 |
3028 | |
3029 } // namespace dart | 2712 } // namespace dart |
3030 | 2713 |
3031 #endif // defined TARGET_ARCH_IA32 | 2714 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |