| 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 |