OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // |
| 5 // Modified by the Subzero authors. |
| 6 // |
| 7 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// |
| 8 // |
| 9 // The Subzero Code Generator |
| 10 // |
| 11 // This file is distributed under the University of Illinois Open Source |
| 12 // License. See LICENSE.TXT for details. |
| 13 // |
| 14 //===----------------------------------------------------------------------===// |
| 15 // |
| 16 // This file implements the Assembler class for x86-32. |
| 17 // |
| 18 //===----------------------------------------------------------------------===// |
| 19 |
| 20 #include "assembler_ia32.h" |
| 21 #include "IceMemoryRegion.h" |
| 22 |
| 23 namespace Ice { |
| 24 namespace x86 { |
| 25 |
| 26 class DirectCallRelocation : public AssemblerFixup { |
| 27 public: |
| 28 static DirectCallRelocation *create(Assembler *Asm, FixupKind Kind, |
| 29 const ConstantRelocatable *Sym) { |
| 30 return new (Asm->Allocate<DirectCallRelocation>()) |
| 31 DirectCallRelocation(Kind, Sym); |
| 32 } |
| 33 |
| 34 void Process(const MemoryRegion ®ion, intptr_t position) { |
| 35 // Direct calls are relative to the following instruction on x86. |
| 36 int32_t pointer = region.Load<int32_t>(position); |
| 37 int32_t delta = region.start() + position + sizeof(int32_t); |
| 38 region.Store<int32_t>(position, pointer - delta); |
| 39 } |
| 40 |
| 41 private: |
| 42 DirectCallRelocation(FixupKind Kind, const ConstantRelocatable *Sym) |
| 43 : AssemblerFixup(Kind, Sym) {} |
| 44 }; |
| 45 |
| 46 void AssemblerX86::call(Register reg) { |
| 47 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 48 EmitUint8(0xFF); |
| 49 EmitRegisterOperand(2, reg); |
| 50 } |
| 51 |
| 52 void AssemblerX86::call(const Address &address) { |
| 53 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 54 EmitUint8(0xFF); |
| 55 EmitOperand(2, address); |
| 56 } |
| 57 |
| 58 void AssemblerX86::call(Label *label) { |
| 59 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 60 EmitUint8(0xE8); |
| 61 static const int kSize = 5; |
| 62 EmitLabel(label, kSize); |
| 63 } |
| 64 |
| 65 void AssemblerX86::call(const ConstantRelocatable *label) { |
| 66 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 67 intptr_t call_start = buffer_.GetPosition(); |
| 68 EmitUint8(0xE8); |
| 69 EmitFixup(DirectCallRelocation::create(this, FK_PcRel_4, label)); |
| 70 EmitInt32(-4); |
| 71 assert((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
| 72 } |
| 73 |
| 74 void AssemblerX86::pushl(Register reg) { |
| 75 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 76 EmitUint8(0x50 + reg); |
| 77 } |
| 78 |
| 79 void AssemblerX86::pushl(const Address &address) { |
| 80 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 81 EmitUint8(0xFF); |
| 82 EmitOperand(6, address); |
| 83 } |
| 84 |
| 85 void AssemblerX86::pushl(const Immediate &imm) { |
| 86 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 87 EmitUint8(0x68); |
| 88 EmitImmediate(imm); |
| 89 } |
| 90 |
| 91 void AssemblerX86::popl(Register reg) { |
| 92 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 93 EmitUint8(0x58 + reg); |
| 94 } |
| 95 |
| 96 void AssemblerX86::popl(const Address &address) { |
| 97 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 98 EmitUint8(0x8F); |
| 99 EmitOperand(0, address); |
| 100 } |
| 101 |
| 102 void AssemblerX86::pushal() { |
| 103 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 104 EmitUint8(0x60); |
| 105 } |
| 106 |
| 107 void AssemblerX86::popal() { |
| 108 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 109 EmitUint8(0x61); |
| 110 } |
| 111 |
| 112 void AssemblerX86::setcc(Condition condition, ByteRegister dst) { |
| 113 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 114 EmitUint8(0x0F); |
| 115 EmitUint8(0x90 + condition); |
| 116 EmitUint8(0xC0 + dst); |
| 117 } |
| 118 |
| 119 void AssemblerX86::movl(Register dst, const Immediate &imm) { |
| 120 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 121 EmitUint8(0xB8 + dst); |
| 122 EmitImmediate(imm); |
| 123 } |
| 124 |
| 125 void AssemblerX86::movl(Register dst, Register src) { |
| 126 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 127 EmitUint8(0x89); |
| 128 EmitRegisterOperand(src, dst); |
| 129 } |
| 130 |
| 131 void AssemblerX86::movl(Register dst, const Address &src) { |
| 132 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 133 EmitUint8(0x8B); |
| 134 EmitOperand(dst, src); |
| 135 } |
| 136 |
| 137 void AssemblerX86::movl(const Address &dst, Register src) { |
| 138 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 139 EmitUint8(0x89); |
| 140 EmitOperand(src, dst); |
| 141 } |
| 142 |
| 143 void AssemblerX86::movl(const Address &dst, const Immediate &imm) { |
| 144 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 145 EmitUint8(0xC7); |
| 146 EmitOperand(0, dst); |
| 147 EmitImmediate(imm); |
| 148 } |
| 149 |
| 150 void AssemblerX86::movzxb(Register dst, ByteRegister src) { |
| 151 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 152 EmitUint8(0x0F); |
| 153 EmitUint8(0xB6); |
| 154 EmitRegisterOperand(dst, src); |
| 155 } |
| 156 |
| 157 void AssemblerX86::movzxb(Register dst, const Address &src) { |
| 158 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 159 EmitUint8(0x0F); |
| 160 EmitUint8(0xB6); |
| 161 EmitOperand(dst, src); |
| 162 } |
| 163 |
| 164 void AssemblerX86::movsxb(Register dst, ByteRegister src) { |
| 165 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 166 EmitUint8(0x0F); |
| 167 EmitUint8(0xBE); |
| 168 EmitRegisterOperand(dst, src); |
| 169 } |
| 170 |
| 171 void AssemblerX86::movsxb(Register dst, const Address &src) { |
| 172 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 173 EmitUint8(0x0F); |
| 174 EmitUint8(0xBE); |
| 175 EmitOperand(dst, src); |
| 176 } |
| 177 |
| 178 void AssemblerX86::movb(ByteRegister dst, const Address &src) { |
| 179 (void)dst; |
| 180 (void)src; |
| 181 // FATAL |
| 182 llvm_unreachable("Use movzxb or movsxb instead."); |
| 183 } |
| 184 |
| 185 void AssemblerX86::movb(const Address &dst, ByteRegister src) { |
| 186 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 187 EmitUint8(0x88); |
| 188 EmitOperand(src, dst); |
| 189 } |
| 190 |
| 191 void AssemblerX86::movb(const Address &dst, const Immediate &imm) { |
| 192 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 193 EmitUint8(0xC6); |
| 194 EmitOperand(EAX, dst); |
| 195 assert(imm.is_int8()); |
| 196 EmitUint8(imm.value() & 0xFF); |
| 197 } |
| 198 |
| 199 void AssemblerX86::movzxw(Register dst, Register src) { |
| 200 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 201 EmitUint8(0x0F); |
| 202 EmitUint8(0xB7); |
| 203 EmitRegisterOperand(dst, src); |
| 204 } |
| 205 |
| 206 void AssemblerX86::movzxw(Register dst, const Address &src) { |
| 207 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 208 EmitUint8(0x0F); |
| 209 EmitUint8(0xB7); |
| 210 EmitOperand(dst, src); |
| 211 } |
| 212 |
| 213 void AssemblerX86::movsxw(Register dst, Register src) { |
| 214 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 215 EmitUint8(0x0F); |
| 216 EmitUint8(0xBF); |
| 217 EmitRegisterOperand(dst, src); |
| 218 } |
| 219 |
| 220 void AssemblerX86::movsxw(Register dst, const Address &src) { |
| 221 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 222 EmitUint8(0x0F); |
| 223 EmitUint8(0xBF); |
| 224 EmitOperand(dst, src); |
| 225 } |
| 226 |
| 227 void AssemblerX86::movw(Register dst, const Address &src) { |
| 228 (void)dst; |
| 229 (void)src; |
| 230 // FATAL |
| 231 llvm_unreachable("Use movzxw or movsxw instead."); |
| 232 } |
| 233 |
| 234 void AssemblerX86::movw(const Address &dst, Register src) { |
| 235 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 236 EmitOperandSizeOverride(); |
| 237 EmitUint8(0x89); |
| 238 EmitOperand(src, dst); |
| 239 } |
| 240 |
| 241 void AssemblerX86::leal(Register dst, const Address &src) { |
| 242 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 243 EmitUint8(0x8D); |
| 244 EmitOperand(dst, src); |
| 245 } |
| 246 |
| 247 void AssemblerX86::cmov(Condition cond, Register dst, Register src) { |
| 248 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 249 EmitUint8(0x0F); |
| 250 EmitUint8(0x40 + cond); |
| 251 EmitRegisterOperand(dst, src); |
| 252 } |
| 253 |
| 254 void AssemblerX86::rep_movsb() { |
| 255 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 256 EmitUint8(0xF3); |
| 257 EmitUint8(0xA4); |
| 258 } |
| 259 |
| 260 void AssemblerX86::movss(XmmRegister dst, const Address &src) { |
| 261 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 262 EmitUint8(0xF3); |
| 263 EmitUint8(0x0F); |
| 264 EmitUint8(0x10); |
| 265 EmitOperand(dst, src); |
| 266 } |
| 267 |
| 268 void AssemblerX86::movss(const Address &dst, XmmRegister src) { |
| 269 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 270 EmitUint8(0xF3); |
| 271 EmitUint8(0x0F); |
| 272 EmitUint8(0x11); |
| 273 EmitOperand(src, dst); |
| 274 } |
| 275 |
| 276 void AssemblerX86::movss(XmmRegister dst, XmmRegister src) { |
| 277 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 278 EmitUint8(0xF3); |
| 279 EmitUint8(0x0F); |
| 280 EmitUint8(0x11); |
| 281 EmitXmmRegisterOperand(src, dst); |
| 282 } |
| 283 |
| 284 void AssemblerX86::movd(XmmRegister dst, Register src) { |
| 285 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 286 EmitUint8(0x66); |
| 287 EmitUint8(0x0F); |
| 288 EmitUint8(0x6E); |
| 289 EmitOperand(dst, Operand(src)); |
| 290 } |
| 291 |
| 292 void AssemblerX86::movd(Register dst, XmmRegister src) { |
| 293 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 294 EmitUint8(0x66); |
| 295 EmitUint8(0x0F); |
| 296 EmitUint8(0x7E); |
| 297 EmitOperand(src, Operand(dst)); |
| 298 } |
| 299 |
| 300 void AssemblerX86::movq(const Address &dst, XmmRegister src) { |
| 301 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 302 EmitUint8(0x66); |
| 303 EmitUint8(0x0F); |
| 304 EmitUint8(0xD6); |
| 305 EmitOperand(src, Operand(dst)); |
| 306 } |
| 307 |
| 308 void AssemblerX86::movq(XmmRegister dst, const Address &src) { |
| 309 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 310 EmitUint8(0xF3); |
| 311 EmitUint8(0x0F); |
| 312 EmitUint8(0x7E); |
| 313 EmitOperand(dst, Operand(src)); |
| 314 } |
| 315 |
| 316 // TODO(jvoung): In these xmm1, xmm2/mXX cases, the opcodes don't vary |
| 317 // based on operand-type. Should we just have an "addss_start()" method, |
| 318 // and then the caller can do EmitXmmRegisterOperand(dst, src) |
| 319 // or EmitOperand(dst, src)? Then we don't have to fill in the missing |
| 320 // variants which only handle Xmm, Xmm (but not Xmm, mXX). |
| 321 // Only thing is we'll be diverging, and we'll end up making the |
| 322 // EmitXmmRegisterOperand, etc. public instead of private. |
| 323 |
| 324 void AssemblerX86::addss(XmmRegister dst, XmmRegister src) { |
| 325 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 326 EmitUint8(0xF3); |
| 327 EmitUint8(0x0F); |
| 328 EmitUint8(0x58); |
| 329 EmitXmmRegisterOperand(dst, src); |
| 330 } |
| 331 |
| 332 void AssemblerX86::addss(XmmRegister dst, const Address &src) { |
| 333 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 334 EmitUint8(0xF3); |
| 335 EmitUint8(0x0F); |
| 336 EmitUint8(0x58); |
| 337 EmitOperand(dst, src); |
| 338 } |
| 339 |
| 340 void AssemblerX86::subss(XmmRegister dst, XmmRegister src) { |
| 341 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 342 EmitUint8(0xF3); |
| 343 EmitUint8(0x0F); |
| 344 EmitUint8(0x5C); |
| 345 EmitXmmRegisterOperand(dst, src); |
| 346 } |
| 347 |
| 348 void AssemblerX86::subss(XmmRegister dst, const Address &src) { |
| 349 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 350 EmitUint8(0xF3); |
| 351 EmitUint8(0x0F); |
| 352 EmitUint8(0x5C); |
| 353 EmitOperand(dst, src); |
| 354 } |
| 355 |
| 356 void AssemblerX86::mulss(XmmRegister dst, XmmRegister src) { |
| 357 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 358 EmitUint8(0xF3); |
| 359 EmitUint8(0x0F); |
| 360 EmitUint8(0x59); |
| 361 EmitXmmRegisterOperand(dst, src); |
| 362 } |
| 363 |
| 364 void AssemblerX86::mulss(XmmRegister dst, const Address &src) { |
| 365 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 366 EmitUint8(0xF3); |
| 367 EmitUint8(0x0F); |
| 368 EmitUint8(0x59); |
| 369 EmitOperand(dst, src); |
| 370 } |
| 371 |
| 372 void AssemblerX86::divss(XmmRegister dst, XmmRegister src) { |
| 373 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 374 EmitUint8(0xF3); |
| 375 EmitUint8(0x0F); |
| 376 EmitUint8(0x5E); |
| 377 EmitXmmRegisterOperand(dst, src); |
| 378 } |
| 379 |
| 380 void AssemblerX86::divss(XmmRegister dst, const Address &src) { |
| 381 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 382 EmitUint8(0xF3); |
| 383 EmitUint8(0x0F); |
| 384 EmitUint8(0x5E); |
| 385 EmitOperand(dst, src); |
| 386 } |
| 387 |
| 388 void AssemblerX86::flds(const Address &src) { |
| 389 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 390 EmitUint8(0xD9); |
| 391 EmitOperand(0, src); |
| 392 } |
| 393 |
| 394 void AssemblerX86::fstps(const Address &dst) { |
| 395 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 396 EmitUint8(0xD9); |
| 397 EmitOperand(3, dst); |
| 398 } |
| 399 |
| 400 void AssemblerX86::movsd(XmmRegister dst, const Address &src) { |
| 401 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 402 EmitUint8(0xF2); |
| 403 EmitUint8(0x0F); |
| 404 EmitUint8(0x10); |
| 405 EmitOperand(dst, src); |
| 406 } |
| 407 |
| 408 void AssemblerX86::movsd(const Address &dst, XmmRegister src) { |
| 409 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 410 EmitUint8(0xF2); |
| 411 EmitUint8(0x0F); |
| 412 EmitUint8(0x11); |
| 413 EmitOperand(src, dst); |
| 414 } |
| 415 |
| 416 void AssemblerX86::movsd(XmmRegister dst, XmmRegister src) { |
| 417 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 418 EmitUint8(0xF2); |
| 419 EmitUint8(0x0F); |
| 420 EmitUint8(0x11); |
| 421 EmitXmmRegisterOperand(src, dst); |
| 422 } |
| 423 |
| 424 void AssemblerX86::movaps(XmmRegister dst, XmmRegister src) { |
| 425 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 426 EmitUint8(0x0F); |
| 427 EmitUint8(0x28); |
| 428 EmitXmmRegisterOperand(dst, src); |
| 429 } |
| 430 |
| 431 void AssemblerX86::movups(XmmRegister dst, const Address &src) { |
| 432 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 433 EmitUint8(0x0F); |
| 434 EmitUint8(0x10); |
| 435 EmitOperand(dst, src); |
| 436 } |
| 437 |
| 438 void AssemblerX86::movups(const Address &dst, XmmRegister src) { |
| 439 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 440 EmitUint8(0x0F); |
| 441 EmitUint8(0x11); |
| 442 EmitOperand(src, dst); |
| 443 } |
| 444 |
| 445 void AssemblerX86::addsd(XmmRegister dst, XmmRegister src) { |
| 446 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 447 EmitUint8(0xF2); |
| 448 EmitUint8(0x0F); |
| 449 EmitUint8(0x58); |
| 450 EmitXmmRegisterOperand(dst, src); |
| 451 } |
| 452 |
| 453 void AssemblerX86::addsd(XmmRegister dst, const Address &src) { |
| 454 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 455 EmitUint8(0xF2); |
| 456 EmitUint8(0x0F); |
| 457 EmitUint8(0x58); |
| 458 EmitOperand(dst, src); |
| 459 } |
| 460 |
| 461 void AssemblerX86::padd(Type Ty, XmmRegister dst, XmmRegister src) { |
| 462 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 463 EmitUint8(0x66); |
| 464 EmitUint8(0x0F); |
| 465 if (Ty == IceType_i8 || Ty == IceType_i1) { |
| 466 EmitUint8(0xFC); |
| 467 } else if (Ty == IceType_i16) { |
| 468 EmitUint8(0xFD); |
| 469 } else { |
| 470 EmitUint8(0xFE); |
| 471 } |
| 472 EmitXmmRegisterOperand(dst, src); |
| 473 } |
| 474 |
| 475 void AssemblerX86::padd(Type Ty, XmmRegister dst, const Address &src) { |
| 476 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 477 EmitUint8(0x66); |
| 478 EmitUint8(0x0F); |
| 479 if (Ty == IceType_i8 || Ty == IceType_i1) { |
| 480 EmitUint8(0xFC); |
| 481 } else if (Ty == IceType_i16) { |
| 482 EmitUint8(0xFD); |
| 483 } else { |
| 484 EmitUint8(0xFE); |
| 485 } |
| 486 EmitOperand(dst, src); |
| 487 } |
| 488 |
| 489 void AssemblerX86::psub(Type Ty, XmmRegister dst, XmmRegister src) { |
| 490 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 491 EmitUint8(0x66); |
| 492 EmitUint8(0x0F); |
| 493 if (Ty == IceType_i8 || Ty == IceType_i1) { |
| 494 EmitUint8(0xF8); |
| 495 } else if (Ty == IceType_i16) { |
| 496 EmitUint8(0xF9); |
| 497 } else { |
| 498 EmitUint8(0xFA); |
| 499 } |
| 500 EmitXmmRegisterOperand(dst, src); |
| 501 } |
| 502 |
| 503 void AssemblerX86::psub(Type Ty, XmmRegister dst, const Address &src) { |
| 504 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 505 EmitUint8(0x66); |
| 506 EmitUint8(0x0F); |
| 507 if (Ty == IceType_i8 || Ty == IceType_i1) { |
| 508 EmitUint8(0xF8); |
| 509 } else if (Ty == IceType_i16) { |
| 510 EmitUint8(0xF9); |
| 511 } else { |
| 512 EmitUint8(0xFA); |
| 513 } |
| 514 EmitOperand(dst, src); |
| 515 } |
| 516 |
| 517 void AssemblerX86::addps(XmmRegister dst, XmmRegister src) { |
| 518 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 519 EmitUint8(0x0F); |
| 520 EmitUint8(0x58); |
| 521 EmitXmmRegisterOperand(dst, src); |
| 522 } |
| 523 |
| 524 void AssemblerX86::addps(XmmRegister dst, const Address &src) { |
| 525 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 526 EmitUint8(0x0F); |
| 527 EmitUint8(0x58); |
| 528 EmitOperand(dst, src); |
| 529 } |
| 530 |
| 531 void AssemblerX86::subps(XmmRegister dst, XmmRegister src) { |
| 532 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 533 EmitUint8(0x0F); |
| 534 EmitUint8(0x5C); |
| 535 EmitXmmRegisterOperand(dst, src); |
| 536 } |
| 537 |
| 538 void AssemblerX86::subps(XmmRegister dst, const Address &src) { |
| 539 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 540 EmitUint8(0x0F); |
| 541 EmitUint8(0x5C); |
| 542 EmitOperand(dst, src); |
| 543 } |
| 544 |
| 545 void AssemblerX86::divps(XmmRegister dst, XmmRegister src) { |
| 546 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 547 EmitUint8(0x0F); |
| 548 EmitUint8(0x5E); |
| 549 EmitXmmRegisterOperand(dst, src); |
| 550 } |
| 551 |
| 552 void AssemblerX86::divps(XmmRegister dst, const Address &src) { |
| 553 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 554 EmitUint8(0x0F); |
| 555 EmitUint8(0x5E); |
| 556 EmitOperand(dst, src); |
| 557 } |
| 558 |
| 559 void AssemblerX86::mulps(XmmRegister dst, XmmRegister src) { |
| 560 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 561 EmitUint8(0x0F); |
| 562 EmitUint8(0x59); |
| 563 EmitXmmRegisterOperand(dst, src); |
| 564 } |
| 565 |
| 566 void AssemblerX86::mulps(XmmRegister dst, const Address &src) { |
| 567 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 568 EmitUint8(0x0F); |
| 569 EmitUint8(0x59); |
| 570 EmitOperand(dst, src); |
| 571 } |
| 572 |
| 573 void AssemblerX86::minps(XmmRegister dst, XmmRegister src) { |
| 574 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 575 EmitUint8(0x0F); |
| 576 EmitUint8(0x5D); |
| 577 EmitXmmRegisterOperand(dst, src); |
| 578 } |
| 579 |
| 580 void AssemblerX86::maxps(XmmRegister dst, XmmRegister src) { |
| 581 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 582 EmitUint8(0x0F); |
| 583 EmitUint8(0x5F); |
| 584 EmitXmmRegisterOperand(dst, src); |
| 585 } |
| 586 |
| 587 void AssemblerX86::andps(XmmRegister dst, XmmRegister src) { |
| 588 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 589 EmitUint8(0x0F); |
| 590 EmitUint8(0x54); |
| 591 EmitXmmRegisterOperand(dst, src); |
| 592 } |
| 593 |
| 594 void AssemblerX86::andps(XmmRegister dst, const Address &src) { |
| 595 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 596 EmitUint8(0x0F); |
| 597 EmitUint8(0x54); |
| 598 EmitOperand(dst, src); |
| 599 } |
| 600 |
| 601 void AssemblerX86::orps(XmmRegister dst, XmmRegister src) { |
| 602 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 603 EmitUint8(0x0F); |
| 604 EmitUint8(0x56); |
| 605 EmitXmmRegisterOperand(dst, src); |
| 606 } |
| 607 |
| 608 void AssemblerX86::cmpps(XmmRegister dst, XmmRegister src, |
| 609 uint8_t CmpCondition) { |
| 610 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 611 EmitUint8(0x0F); |
| 612 EmitUint8(0xC2); |
| 613 EmitXmmRegisterOperand(dst, src); |
| 614 EmitUint8(CmpCondition); |
| 615 } |
| 616 |
| 617 void AssemblerX86::cmpps(XmmRegister dst, const Address &src, |
| 618 uint8_t CmpCondition) { |
| 619 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 620 EmitUint8(0x0F); |
| 621 EmitUint8(0xC2); |
| 622 EmitOperand(dst, src); |
| 623 EmitUint8(CmpCondition); |
| 624 } |
| 625 |
| 626 void AssemblerX86::sqrtps(XmmRegister dst) { |
| 627 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 628 EmitUint8(0x0F); |
| 629 EmitUint8(0x51); |
| 630 EmitXmmRegisterOperand(dst, dst); |
| 631 } |
| 632 |
| 633 void AssemblerX86::rsqrtps(XmmRegister dst) { |
| 634 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 635 EmitUint8(0x0F); |
| 636 EmitUint8(0x52); |
| 637 EmitXmmRegisterOperand(dst, dst); |
| 638 } |
| 639 |
| 640 void AssemblerX86::reciprocalps(XmmRegister dst) { |
| 641 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 642 EmitUint8(0x0F); |
| 643 EmitUint8(0x53); |
| 644 EmitXmmRegisterOperand(dst, dst); |
| 645 } |
| 646 |
| 647 void AssemblerX86::movhlps(XmmRegister dst, XmmRegister src) { |
| 648 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 649 EmitUint8(0x0F); |
| 650 EmitUint8(0x12); |
| 651 EmitXmmRegisterOperand(dst, src); |
| 652 } |
| 653 |
| 654 void AssemblerX86::movlhps(XmmRegister dst, XmmRegister src) { |
| 655 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 656 EmitUint8(0x0F); |
| 657 EmitUint8(0x16); |
| 658 EmitXmmRegisterOperand(dst, src); |
| 659 } |
| 660 |
| 661 void AssemblerX86::unpcklps(XmmRegister dst, XmmRegister src) { |
| 662 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 663 EmitUint8(0x0F); |
| 664 EmitUint8(0x14); |
| 665 EmitXmmRegisterOperand(dst, src); |
| 666 } |
| 667 |
| 668 void AssemblerX86::unpckhps(XmmRegister dst, XmmRegister src) { |
| 669 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 670 EmitUint8(0x0F); |
| 671 EmitUint8(0x15); |
| 672 EmitXmmRegisterOperand(dst, src); |
| 673 } |
| 674 |
| 675 void AssemblerX86::unpcklpd(XmmRegister dst, XmmRegister src) { |
| 676 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 677 EmitUint8(0x66); |
| 678 EmitUint8(0x0F); |
| 679 EmitUint8(0x14); |
| 680 EmitXmmRegisterOperand(dst, src); |
| 681 } |
| 682 |
| 683 void AssemblerX86::unpckhpd(XmmRegister dst, XmmRegister src) { |
| 684 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 685 EmitUint8(0x66); |
| 686 EmitUint8(0x0F); |
| 687 EmitUint8(0x15); |
| 688 EmitXmmRegisterOperand(dst, src); |
| 689 } |
| 690 |
| 691 void AssemblerX86::set1ps(XmmRegister dst, Register tmp1, |
| 692 const Immediate &imm) { |
| 693 // Load 32-bit immediate value into tmp1. |
| 694 movl(tmp1, imm); |
| 695 // Move value from tmp1 into dst. |
| 696 movd(dst, tmp1); |
| 697 // Broadcast low lane into other three lanes. |
| 698 shufps(dst, dst, Immediate(0x0)); |
| 699 } |
| 700 |
| 701 void AssemblerX86::shufps(XmmRegister dst, XmmRegister src, |
| 702 const Immediate &imm) { |
| 703 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 704 EmitUint8(0x0F); |
| 705 EmitUint8(0xC6); |
| 706 EmitXmmRegisterOperand(dst, src); |
| 707 assert(imm.is_uint8()); |
| 708 EmitUint8(imm.value()); |
| 709 } |
| 710 |
| 711 void AssemblerX86::addpd(XmmRegister dst, XmmRegister src) { |
| 712 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 713 EmitUint8(0x66); |
| 714 EmitUint8(0x0F); |
| 715 EmitUint8(0x58); |
| 716 EmitXmmRegisterOperand(dst, src); |
| 717 } |
| 718 |
| 719 void AssemblerX86::subpd(XmmRegister dst, XmmRegister src) { |
| 720 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 721 EmitUint8(0x66); |
| 722 EmitUint8(0x0F); |
| 723 EmitUint8(0x5C); |
| 724 EmitXmmRegisterOperand(dst, src); |
| 725 } |
| 726 |
| 727 void AssemblerX86::mulpd(XmmRegister dst, XmmRegister src) { |
| 728 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 729 EmitUint8(0x66); |
| 730 EmitUint8(0x0F); |
| 731 EmitUint8(0x59); |
| 732 EmitXmmRegisterOperand(dst, src); |
| 733 } |
| 734 |
| 735 void AssemblerX86::divpd(XmmRegister dst, XmmRegister src) { |
| 736 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 737 EmitUint8(0x66); |
| 738 EmitUint8(0x0F); |
| 739 EmitUint8(0x5E); |
| 740 EmitXmmRegisterOperand(dst, src); |
| 741 } |
| 742 |
| 743 void AssemblerX86::minpd(XmmRegister dst, XmmRegister src) { |
| 744 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 745 EmitUint8(0x66); |
| 746 EmitUint8(0x0F); |
| 747 EmitUint8(0x5D); |
| 748 EmitXmmRegisterOperand(dst, src); |
| 749 } |
| 750 |
| 751 void AssemblerX86::maxpd(XmmRegister dst, XmmRegister src) { |
| 752 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 753 EmitUint8(0x66); |
| 754 EmitUint8(0x0F); |
| 755 EmitUint8(0x5F); |
| 756 EmitXmmRegisterOperand(dst, src); |
| 757 } |
| 758 |
| 759 void AssemblerX86::sqrtpd(XmmRegister dst) { |
| 760 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 761 EmitUint8(0x66); |
| 762 EmitUint8(0x0F); |
| 763 EmitUint8(0x51); |
| 764 EmitXmmRegisterOperand(dst, dst); |
| 765 } |
| 766 |
| 767 void AssemblerX86::cvtps2pd(XmmRegister dst, XmmRegister src) { |
| 768 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 769 EmitUint8(0x0F); |
| 770 EmitUint8(0x5A); |
| 771 EmitXmmRegisterOperand(dst, src); |
| 772 } |
| 773 |
| 774 void AssemblerX86::cvtpd2ps(XmmRegister dst, XmmRegister src) { |
| 775 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 776 EmitUint8(0x66); |
| 777 EmitUint8(0x0F); |
| 778 EmitUint8(0x5A); |
| 779 EmitXmmRegisterOperand(dst, src); |
| 780 } |
| 781 |
| 782 void AssemblerX86::shufpd(XmmRegister dst, XmmRegister src, |
| 783 const Immediate &imm) { |
| 784 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 785 EmitUint8(0x66); |
| 786 EmitUint8(0x0F); |
| 787 EmitUint8(0xC6); |
| 788 EmitXmmRegisterOperand(dst, src); |
| 789 assert(imm.is_uint8()); |
| 790 EmitUint8(imm.value()); |
| 791 } |
| 792 |
| 793 void AssemblerX86::subsd(XmmRegister dst, XmmRegister src) { |
| 794 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 795 EmitUint8(0xF2); |
| 796 EmitUint8(0x0F); |
| 797 EmitUint8(0x5C); |
| 798 EmitXmmRegisterOperand(dst, src); |
| 799 } |
| 800 |
| 801 void AssemblerX86::subsd(XmmRegister dst, const Address &src) { |
| 802 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 803 EmitUint8(0xF2); |
| 804 EmitUint8(0x0F); |
| 805 EmitUint8(0x5C); |
| 806 EmitOperand(dst, src); |
| 807 } |
| 808 |
| 809 void AssemblerX86::mulsd(XmmRegister dst, XmmRegister src) { |
| 810 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 811 EmitUint8(0xF2); |
| 812 EmitUint8(0x0F); |
| 813 EmitUint8(0x59); |
| 814 EmitXmmRegisterOperand(dst, src); |
| 815 } |
| 816 |
| 817 void AssemblerX86::mulsd(XmmRegister dst, const Address &src) { |
| 818 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 819 EmitUint8(0xF2); |
| 820 EmitUint8(0x0F); |
| 821 EmitUint8(0x59); |
| 822 EmitOperand(dst, src); |
| 823 } |
| 824 |
| 825 void AssemblerX86::divsd(XmmRegister dst, XmmRegister src) { |
| 826 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 827 EmitUint8(0xF2); |
| 828 EmitUint8(0x0F); |
| 829 EmitUint8(0x5E); |
| 830 EmitXmmRegisterOperand(dst, src); |
| 831 } |
| 832 |
| 833 void AssemblerX86::divsd(XmmRegister dst, const Address &src) { |
| 834 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 835 EmitUint8(0xF2); |
| 836 EmitUint8(0x0F); |
| 837 EmitUint8(0x5E); |
| 838 EmitOperand(dst, src); |
| 839 } |
| 840 |
| 841 void AssemblerX86::cvtsi2ss(XmmRegister dst, Register src) { |
| 842 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 843 EmitUint8(0xF3); |
| 844 EmitUint8(0x0F); |
| 845 EmitUint8(0x2A); |
| 846 EmitOperand(dst, Operand(src)); |
| 847 } |
| 848 |
| 849 void AssemblerX86::cvtsi2sd(XmmRegister dst, Register src) { |
| 850 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 851 EmitUint8(0xF2); |
| 852 EmitUint8(0x0F); |
| 853 EmitUint8(0x2A); |
| 854 EmitOperand(dst, Operand(src)); |
| 855 } |
| 856 |
| 857 void AssemblerX86::cvtss2si(Register dst, XmmRegister src) { |
| 858 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 859 EmitUint8(0xF3); |
| 860 EmitUint8(0x0F); |
| 861 EmitUint8(0x2D); |
| 862 EmitXmmRegisterOperand(dst, src); |
| 863 } |
| 864 |
| 865 void AssemblerX86::cvtss2sd(XmmRegister dst, XmmRegister src) { |
| 866 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 867 EmitUint8(0xF3); |
| 868 EmitUint8(0x0F); |
| 869 EmitUint8(0x5A); |
| 870 EmitXmmRegisterOperand(dst, src); |
| 871 } |
| 872 |
| 873 void AssemblerX86::cvtsd2si(Register dst, XmmRegister src) { |
| 874 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 875 EmitUint8(0xF2); |
| 876 EmitUint8(0x0F); |
| 877 EmitUint8(0x2D); |
| 878 EmitXmmRegisterOperand(dst, src); |
| 879 } |
| 880 |
| 881 void AssemblerX86::cvttss2si(Register dst, XmmRegister src) { |
| 882 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 883 EmitUint8(0xF3); |
| 884 EmitUint8(0x0F); |
| 885 EmitUint8(0x2C); |
| 886 EmitXmmRegisterOperand(dst, src); |
| 887 } |
| 888 |
| 889 void AssemblerX86::cvttsd2si(Register dst, XmmRegister src) { |
| 890 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 891 EmitUint8(0xF2); |
| 892 EmitUint8(0x0F); |
| 893 EmitUint8(0x2C); |
| 894 EmitXmmRegisterOperand(dst, src); |
| 895 } |
| 896 |
| 897 void AssemblerX86::cvtsd2ss(XmmRegister dst, XmmRegister src) { |
| 898 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 899 EmitUint8(0xF2); |
| 900 EmitUint8(0x0F); |
| 901 EmitUint8(0x5A); |
| 902 EmitXmmRegisterOperand(dst, src); |
| 903 } |
| 904 |
| 905 void AssemblerX86::cvtdq2pd(XmmRegister dst, XmmRegister src) { |
| 906 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 907 EmitUint8(0xF3); |
| 908 EmitUint8(0x0F); |
| 909 EmitUint8(0xE6); |
| 910 EmitXmmRegisterOperand(dst, src); |
| 911 } |
| 912 |
| 913 void AssemblerX86::ucomiss(XmmRegister a, XmmRegister b) { |
| 914 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 915 EmitUint8(0x0F); |
| 916 EmitUint8(0x2E); |
| 917 EmitXmmRegisterOperand(a, b); |
| 918 } |
| 919 |
| 920 void AssemblerX86::ucomiss(XmmRegister a, const Address &b) { |
| 921 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 922 EmitUint8(0x0F); |
| 923 EmitUint8(0x2E); |
| 924 EmitOperand(a, b); |
| 925 } |
| 926 |
| 927 void AssemblerX86::ucomisd(XmmRegister a, XmmRegister b) { |
| 928 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 929 EmitUint8(0x66); |
| 930 EmitUint8(0x0F); |
| 931 EmitUint8(0x2E); |
| 932 EmitXmmRegisterOperand(a, b); |
| 933 } |
| 934 |
| 935 void AssemblerX86::ucomisd(XmmRegister a, const Address &b) { |
| 936 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 937 EmitUint8(0x66); |
| 938 EmitUint8(0x0F); |
| 939 EmitUint8(0x2E); |
| 940 EmitOperand(a, b); |
| 941 } |
| 942 |
| 943 void AssemblerX86::movmskpd(Register dst, XmmRegister src) { |
| 944 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 945 EmitUint8(0x66); |
| 946 EmitUint8(0x0F); |
| 947 EmitUint8(0x50); |
| 948 EmitXmmRegisterOperand(dst, src); |
| 949 } |
| 950 |
| 951 void AssemblerX86::movmskps(Register dst, XmmRegister src) { |
| 952 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 953 EmitUint8(0x0F); |
| 954 EmitUint8(0x50); |
| 955 EmitXmmRegisterOperand(dst, src); |
| 956 } |
| 957 |
| 958 void AssemblerX86::sqrtsd(XmmRegister dst, const Address &src) { |
| 959 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 960 EmitUint8(0xF2); |
| 961 EmitUint8(0x0F); |
| 962 EmitUint8(0x51); |
| 963 EmitOperand(dst, src); |
| 964 } |
| 965 |
| 966 void AssemblerX86::sqrtsd(XmmRegister dst, XmmRegister src) { |
| 967 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 968 EmitUint8(0xF2); |
| 969 EmitUint8(0x0F); |
| 970 EmitUint8(0x51); |
| 971 EmitXmmRegisterOperand(dst, src); |
| 972 } |
| 973 |
| 974 void AssemblerX86::sqrtss(XmmRegister dst, const Address &src) { |
| 975 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 976 EmitUint8(0xF3); |
| 977 EmitUint8(0x0F); |
| 978 EmitUint8(0x51); |
| 979 EmitOperand(dst, src); |
| 980 } |
| 981 |
| 982 void AssemblerX86::sqrtss(XmmRegister dst, XmmRegister src) { |
| 983 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 984 EmitUint8(0xF3); |
| 985 EmitUint8(0x0F); |
| 986 EmitUint8(0x51); |
| 987 EmitXmmRegisterOperand(dst, src); |
| 988 } |
| 989 |
| 990 void AssemblerX86::xorpd(XmmRegister dst, const Address &src) { |
| 991 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 992 EmitUint8(0x66); |
| 993 EmitUint8(0x0F); |
| 994 EmitUint8(0x57); |
| 995 EmitOperand(dst, src); |
| 996 } |
| 997 |
| 998 void AssemblerX86::xorpd(XmmRegister dst, XmmRegister src) { |
| 999 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1000 EmitUint8(0x66); |
| 1001 EmitUint8(0x0F); |
| 1002 EmitUint8(0x57); |
| 1003 EmitXmmRegisterOperand(dst, src); |
| 1004 } |
| 1005 |
| 1006 void AssemblerX86::orpd(XmmRegister dst, XmmRegister src) { |
| 1007 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1008 EmitUint8(0x66); |
| 1009 EmitUint8(0x0F); |
| 1010 EmitUint8(0x56); |
| 1011 EmitXmmRegisterOperand(dst, src); |
| 1012 } |
| 1013 |
| 1014 void AssemblerX86::xorps(XmmRegister dst, const Address &src) { |
| 1015 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1016 EmitUint8(0x0F); |
| 1017 EmitUint8(0x57); |
| 1018 EmitOperand(dst, src); |
| 1019 } |
| 1020 |
| 1021 void AssemblerX86::xorps(XmmRegister dst, XmmRegister src) { |
| 1022 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1023 EmitUint8(0x0F); |
| 1024 EmitUint8(0x57); |
| 1025 EmitXmmRegisterOperand(dst, src); |
| 1026 } |
| 1027 |
| 1028 void AssemblerX86::andpd(XmmRegister dst, const Address &src) { |
| 1029 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1030 EmitUint8(0x66); |
| 1031 EmitUint8(0x0F); |
| 1032 EmitUint8(0x54); |
| 1033 EmitOperand(dst, src); |
| 1034 } |
| 1035 |
| 1036 void AssemblerX86::andpd(XmmRegister dst, XmmRegister src) { |
| 1037 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1038 EmitUint8(0x66); |
| 1039 EmitUint8(0x0F); |
| 1040 EmitUint8(0x54); |
| 1041 EmitXmmRegisterOperand(dst, src); |
| 1042 } |
| 1043 |
| 1044 void AssemblerX86::pextrd(Register dst, XmmRegister src, const Immediate &imm) { |
| 1045 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1046 EmitUint8(0x66); |
| 1047 EmitUint8(0x0F); |
| 1048 EmitUint8(0x3A); |
| 1049 EmitUint8(0x16); |
| 1050 EmitOperand(src, Operand(dst)); |
| 1051 assert(imm.is_uint8()); |
| 1052 EmitUint8(imm.value()); |
| 1053 } |
| 1054 |
| 1055 void AssemblerX86::pmovsxdq(XmmRegister dst, XmmRegister src) { |
| 1056 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1057 EmitUint8(0x66); |
| 1058 EmitUint8(0x0F); |
| 1059 EmitUint8(0x38); |
| 1060 EmitUint8(0x25); |
| 1061 EmitXmmRegisterOperand(dst, src); |
| 1062 } |
| 1063 |
| 1064 void AssemblerX86::pcmpeqq(XmmRegister dst, XmmRegister src) { |
| 1065 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1066 EmitUint8(0x66); |
| 1067 EmitUint8(0x0F); |
| 1068 EmitUint8(0x38); |
| 1069 EmitUint8(0x29); |
| 1070 EmitXmmRegisterOperand(dst, src); |
| 1071 } |
| 1072 |
| 1073 void AssemblerX86::pxor(XmmRegister dst, XmmRegister src) { |
| 1074 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1075 EmitUint8(0x66); |
| 1076 EmitUint8(0x0F); |
| 1077 EmitUint8(0xEF); |
| 1078 EmitXmmRegisterOperand(dst, src); |
| 1079 } |
| 1080 |
| 1081 void AssemblerX86::roundsd(XmmRegister dst, XmmRegister src, |
| 1082 RoundingMode mode) { |
| 1083 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1084 EmitUint8(0x66); |
| 1085 EmitUint8(0x0F); |
| 1086 EmitUint8(0x3A); |
| 1087 EmitUint8(0x0B); |
| 1088 EmitXmmRegisterOperand(dst, src); |
| 1089 // Mask precision exeption. |
| 1090 EmitUint8(static_cast<uint8_t>(mode) | 0x8); |
| 1091 } |
| 1092 |
| 1093 void AssemblerX86::fldl(const Address &src) { |
| 1094 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1095 EmitUint8(0xDD); |
| 1096 EmitOperand(0, src); |
| 1097 } |
| 1098 |
| 1099 void AssemblerX86::fstpl(const Address &dst) { |
| 1100 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1101 EmitUint8(0xDD); |
| 1102 EmitOperand(3, dst); |
| 1103 } |
| 1104 |
| 1105 void AssemblerX86::fnstcw(const Address &dst) { |
| 1106 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1107 EmitUint8(0xD9); |
| 1108 EmitOperand(7, dst); |
| 1109 } |
| 1110 |
| 1111 void AssemblerX86::fldcw(const Address &src) { |
| 1112 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1113 EmitUint8(0xD9); |
| 1114 EmitOperand(5, src); |
| 1115 } |
| 1116 |
| 1117 void AssemblerX86::fistpl(const Address &dst) { |
| 1118 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1119 EmitUint8(0xDF); |
| 1120 EmitOperand(7, dst); |
| 1121 } |
| 1122 |
| 1123 void AssemblerX86::fistps(const Address &dst) { |
| 1124 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1125 EmitUint8(0xDB); |
| 1126 EmitOperand(3, dst); |
| 1127 } |
| 1128 |
| 1129 void AssemblerX86::fildl(const Address &src) { |
| 1130 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1131 EmitUint8(0xDF); |
| 1132 EmitOperand(5, src); |
| 1133 } |
| 1134 |
| 1135 void AssemblerX86::filds(const Address &src) { |
| 1136 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1137 EmitUint8(0xDB); |
| 1138 EmitOperand(0, src); |
| 1139 } |
| 1140 |
| 1141 void AssemblerX86::fincstp() { |
| 1142 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1143 EmitUint8(0xD9); |
| 1144 EmitUint8(0xF7); |
| 1145 } |
| 1146 |
| 1147 void AssemblerX86::xchgl(Register dst, Register src) { |
| 1148 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1149 EmitUint8(0x87); |
| 1150 EmitRegisterOperand(dst, src); |
| 1151 } |
| 1152 |
| 1153 void AssemblerX86::cmp(Type Ty, Register reg, const Immediate &imm) { |
| 1154 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1155 if (typeWidthInBytes(Ty) == 1) { |
| 1156 EmitComplexI8(7, Operand(reg), imm); |
| 1157 return; |
| 1158 } |
| 1159 if (Ty == IceType_i16) |
| 1160 EmitOperandSizeOverride(); |
| 1161 EmitComplex(7, Operand(reg), imm); |
| 1162 } |
| 1163 |
| 1164 void AssemblerX86::cmp(Type Ty, Register reg0, Register reg1) { |
| 1165 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1166 if (typeWidthInBytes(Ty) == 1) { |
| 1167 EmitUint8(0x3A); |
| 1168 } else if (Ty == IceType_i16) { |
| 1169 EmitOperandSizeOverride(); |
| 1170 EmitUint8(0x3B); |
| 1171 } else { |
| 1172 EmitUint8(0x3B); |
| 1173 } |
| 1174 EmitRegisterOperand(reg0, reg1); |
| 1175 } |
| 1176 |
| 1177 void AssemblerX86::cmp(Type Ty, Register reg, const Address &address) { |
| 1178 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1179 if (typeWidthInBytes(Ty) == 1) { |
| 1180 EmitUint8(0x3A); |
| 1181 } else if (Ty == IceType_i16) { |
| 1182 EmitOperandSizeOverride(); |
| 1183 EmitUint8(0x3B); |
| 1184 } else { |
| 1185 EmitUint8(0x3B); |
| 1186 } |
| 1187 EmitOperand(reg, address); |
| 1188 } |
| 1189 |
| 1190 void AssemblerX86::cmp(Type Ty, const Address &address, Register reg) { |
| 1191 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1192 if (typeWidthInBytes(Ty) == 1) { |
| 1193 EmitUint8(0x38); |
| 1194 } else if (Ty == IceType_i16) { |
| 1195 EmitOperandSizeOverride(); |
| 1196 EmitUint8(0x39); |
| 1197 } else { |
| 1198 EmitUint8(0x39); |
| 1199 } |
| 1200 EmitOperand(reg, address); |
| 1201 } |
| 1202 |
| 1203 void AssemblerX86::cmp(Type Ty, const Address &address, const Immediate &imm) { |
| 1204 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1205 if (typeWidthInBytes(Ty) == 1) { |
| 1206 EmitComplexI8(7, address, imm); |
| 1207 return; |
| 1208 } |
| 1209 if (Ty == IceType_i16) |
| 1210 EmitOperandSizeOverride(); |
| 1211 EmitComplex(7, address, imm); |
| 1212 } |
| 1213 |
| 1214 void AssemblerX86::testl(Register reg1, Register reg2) { |
| 1215 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1216 EmitUint8(0x85); |
| 1217 EmitRegisterOperand(reg1, reg2); |
| 1218 } |
| 1219 |
| 1220 void AssemblerX86::testl(Register reg, const Immediate &immediate) { |
| 1221 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1222 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) |
| 1223 // we only test the byte register to keep the encoding short. |
| 1224 if (immediate.is_uint8() && reg < 4) { |
| 1225 // Use zero-extended 8-bit immediate. |
| 1226 if (reg == EAX) { |
| 1227 EmitUint8(0xA8); |
| 1228 } else { |
| 1229 EmitUint8(0xF6); |
| 1230 EmitUint8(0xC0 + reg); |
| 1231 } |
| 1232 EmitUint8(immediate.value() & 0xFF); |
| 1233 } else if (reg == EAX) { |
| 1234 // Use short form if the destination is EAX. |
| 1235 EmitUint8(0xA9); |
| 1236 EmitImmediate(immediate); |
| 1237 } else { |
| 1238 EmitUint8(0xF7); |
| 1239 EmitOperand(0, Operand(reg)); |
| 1240 EmitImmediate(immediate); |
| 1241 } |
| 1242 } |
| 1243 |
| 1244 void AssemblerX86::_and(Type Ty, Register dst, Register src) { |
| 1245 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1246 if (typeWidthInBytes(Ty) == 1) { |
| 1247 EmitUint8(0x22); |
| 1248 } else if (Ty == IceType_i16) { |
| 1249 EmitOperandSizeOverride(); |
| 1250 EmitUint8(0x23); |
| 1251 } else { |
| 1252 EmitUint8(0x23); |
| 1253 } |
| 1254 EmitRegisterOperand(dst, src); |
| 1255 } |
| 1256 |
| 1257 void AssemblerX86::_and(Type Ty, Register reg, const Immediate &imm) { |
| 1258 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1259 if (typeWidthInBytes(Ty) == 1) { |
| 1260 EmitComplexI8(4, Operand(reg), imm); |
| 1261 return; |
| 1262 } |
| 1263 if (Ty == IceType_i16) |
| 1264 EmitOperandSizeOverride(); |
| 1265 EmitComplex(4, Operand(reg), imm); |
| 1266 } |
| 1267 |
| 1268 void AssemblerX86::_and(Type Ty, Register dst, const Address &address) { |
| 1269 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1270 if (typeWidthInBytes(Ty) == 1) { |
| 1271 EmitUint8(0x22); |
| 1272 } else if (Ty == IceType_i16) { |
| 1273 EmitOperandSizeOverride(); |
| 1274 EmitUint8(0x23); |
| 1275 } else { |
| 1276 EmitUint8(0x23); |
| 1277 } |
| 1278 EmitOperand(dst, address); |
| 1279 } |
| 1280 |
| 1281 void AssemblerX86::_or(Type Ty, Register dst, Register src) { |
| 1282 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1283 if (typeWidthInBytes(Ty) == 1) { |
| 1284 EmitUint8(0x0A); |
| 1285 } else if (Ty == IceType_i16) { |
| 1286 EmitOperandSizeOverride(); |
| 1287 EmitUint8(0x0B); |
| 1288 } else { |
| 1289 EmitUint8(0x0B); |
| 1290 } |
| 1291 EmitRegisterOperand(dst, src); |
| 1292 } |
| 1293 |
| 1294 void AssemblerX86::_or(Type Ty, Register reg, const Immediate &imm) { |
| 1295 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1296 if (typeWidthInBytes(Ty) == 1) { |
| 1297 EmitComplexI8(1, Operand(reg), imm); |
| 1298 return; |
| 1299 } |
| 1300 if (Ty == IceType_i16) |
| 1301 EmitOperandSizeOverride(); |
| 1302 EmitComplex(1, Operand(reg), imm); |
| 1303 } |
| 1304 |
| 1305 void AssemblerX86::_or(Type Ty, Register dst, const Address &address) { |
| 1306 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1307 if (typeWidthInBytes(Ty) == 1) { |
| 1308 EmitUint8(0x0A); |
| 1309 } else if (Ty == IceType_i16) { |
| 1310 EmitOperandSizeOverride(); |
| 1311 EmitUint8(0x0B); |
| 1312 } else { |
| 1313 EmitUint8(0x0B); |
| 1314 } |
| 1315 EmitOperand(dst, address); |
| 1316 } |
| 1317 |
| 1318 void AssemblerX86::_xor(Type Ty, Register dst, Register src) { |
| 1319 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1320 if (typeWidthInBytes(Ty) == 1) { |
| 1321 EmitUint8(0x32); |
| 1322 } else if (Ty == IceType_i16) { |
| 1323 EmitOperandSizeOverride(); |
| 1324 EmitUint8(0x33); |
| 1325 } else { |
| 1326 EmitUint8(0x33); |
| 1327 } |
| 1328 EmitRegisterOperand(dst, src); |
| 1329 } |
| 1330 |
| 1331 void AssemblerX86::_xor(Type Ty, Register reg, const Immediate &imm) { |
| 1332 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1333 if (typeWidthInBytes(Ty) == 1) { |
| 1334 EmitComplexI8(6, Operand(reg), imm); |
| 1335 return; |
| 1336 } |
| 1337 if (Ty == IceType_i16) |
| 1338 EmitOperandSizeOverride(); |
| 1339 EmitComplex(6, Operand(reg), imm); |
| 1340 } |
| 1341 |
| 1342 void AssemblerX86::_xor(Type Ty, Register dst, const Address &address) { |
| 1343 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1344 if (typeWidthInBytes(Ty) == 1) { |
| 1345 EmitUint8(0x32); |
| 1346 } else if (Ty == IceType_i16) { |
| 1347 EmitOperandSizeOverride(); |
| 1348 EmitUint8(0x33); |
| 1349 } else { |
| 1350 EmitUint8(0x33); |
| 1351 } |
| 1352 EmitOperand(dst, address); |
| 1353 } |
| 1354 |
| 1355 void AssemblerX86::add(Type Ty, Register reg, const Immediate &imm) { |
| 1356 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1357 if (typeWidthInBytes(Ty) == 1) { |
| 1358 EmitComplexI8(0, Operand(reg), imm); |
| 1359 return; |
| 1360 } |
| 1361 if (Ty == IceType_i16) |
| 1362 EmitOperandSizeOverride(); |
| 1363 EmitComplex(0, Operand(reg), imm); |
| 1364 } |
| 1365 |
| 1366 void AssemblerX86::add(Type Ty, const Address &address, Register reg) { |
| 1367 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1368 if (typeWidthInBytes(Ty) == 1) { |
| 1369 EmitUint8(0x00); |
| 1370 } else if (Ty == IceType_i16) { |
| 1371 EmitOperandSizeOverride(); |
| 1372 EmitUint8(0x01); |
| 1373 } else { |
| 1374 EmitUint8(0x01); |
| 1375 } |
| 1376 EmitOperand(reg, address); |
| 1377 } |
| 1378 |
| 1379 void AssemblerX86::add(Type Ty, const Address &address, const Immediate &imm) { |
| 1380 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1381 if (typeWidthInBytes(Ty) == 1) { |
| 1382 EmitComplexI8(0, address, imm); |
| 1383 return; |
| 1384 } |
| 1385 if (Ty == IceType_i16) |
| 1386 EmitOperandSizeOverride(); |
| 1387 EmitComplex(0, address, imm); |
| 1388 } |
| 1389 |
| 1390 // TODO(jvoung): In these cases, Reg-Reg and Reg-Mem are very similar. |
| 1391 // Instead of using EmitRegisterOperand() it is possible to use |
| 1392 // EmitOperand(dst, Operand(src)), and then they would be identical. |
| 1393 // Then the only outlier is Reg-Imm. |
| 1394 |
| 1395 void AssemblerX86::add(Type Ty, Register dst, Register src) { |
| 1396 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1397 if (typeWidthInBytes(Ty) == 1) { |
| 1398 EmitUint8(0x02); |
| 1399 } else if (Ty == IceType_i16) { |
| 1400 EmitOperandSizeOverride(); |
| 1401 EmitUint8(0x03); |
| 1402 } else { |
| 1403 EmitUint8(0x03); |
| 1404 } |
| 1405 EmitRegisterOperand(dst, src); |
| 1406 } |
| 1407 |
| 1408 void AssemblerX86::add(Type Ty, Register reg, const Address &address) { |
| 1409 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1410 if (typeWidthInBytes(Ty) == 1) { |
| 1411 EmitUint8(0x02); |
| 1412 } else if (Ty == IceType_i16) { |
| 1413 EmitOperandSizeOverride(); |
| 1414 EmitUint8(0x03); |
| 1415 } else { |
| 1416 EmitUint8(0x03); |
| 1417 } |
| 1418 EmitOperand(reg, address); |
| 1419 } |
| 1420 |
| 1421 void AssemblerX86::adc(Type Ty, Register reg, const Immediate &imm) { |
| 1422 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1423 if (typeWidthInBytes(Ty) == 1) { |
| 1424 EmitComplexI8(2, Operand(reg), imm); |
| 1425 return; |
| 1426 } |
| 1427 if (Ty == IceType_i16) |
| 1428 EmitOperandSizeOverride(); |
| 1429 EmitComplex(2, Operand(reg), imm); |
| 1430 } |
| 1431 |
| 1432 void AssemblerX86::adc(Type Ty, Register dst, Register src) { |
| 1433 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1434 if (typeWidthInBytes(Ty) == 1) { |
| 1435 EmitUint8(0x12); |
| 1436 } else if (Ty == IceType_i16) { |
| 1437 EmitOperandSizeOverride(); |
| 1438 EmitUint8(0x13); |
| 1439 } else { |
| 1440 EmitUint8(0x13); |
| 1441 } |
| 1442 EmitRegisterOperand(dst, src); |
| 1443 } |
| 1444 |
| 1445 void AssemblerX86::adc(Type Ty, Register dst, const Address &address) { |
| 1446 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1447 if (typeWidthInBytes(Ty) == 1) { |
| 1448 EmitUint8(0x12); |
| 1449 } else if (Ty == IceType_i16) { |
| 1450 EmitOperandSizeOverride(); |
| 1451 EmitUint8(0x13); |
| 1452 } else { |
| 1453 EmitUint8(0x13); |
| 1454 } |
| 1455 EmitOperand(dst, address); |
| 1456 } |
| 1457 |
| 1458 void AssemblerX86::sub(Type Ty, Register dst, Register src) { |
| 1459 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1460 if (typeWidthInBytes(Ty) == 1) { |
| 1461 EmitUint8(0x2A); |
| 1462 } else if (Ty == IceType_i16) { |
| 1463 EmitOperandSizeOverride(); |
| 1464 EmitUint8(0x2B); |
| 1465 } else { |
| 1466 EmitUint8(0x2B); |
| 1467 } |
| 1468 EmitRegisterOperand(dst, src); |
| 1469 } |
| 1470 |
| 1471 void AssemblerX86::sub(Type Ty, Register reg, const Immediate &imm) { |
| 1472 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1473 if (typeWidthInBytes(Ty) == 1) { |
| 1474 EmitComplexI8(5, Operand(reg), imm); |
| 1475 return; |
| 1476 } |
| 1477 if (Ty == IceType_i16) |
| 1478 EmitOperandSizeOverride(); |
| 1479 EmitComplex(5, Operand(reg), imm); |
| 1480 } |
| 1481 |
| 1482 void AssemblerX86::sub(Type Ty, Register reg, const Address &address) { |
| 1483 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1484 if (typeWidthInBytes(Ty) == 1) { |
| 1485 EmitUint8(0x2A); |
| 1486 } else if (Ty == IceType_i16) { |
| 1487 EmitOperandSizeOverride(); |
| 1488 EmitUint8(0x2B); |
| 1489 } else { |
| 1490 EmitUint8(0x2B); |
| 1491 } |
| 1492 EmitOperand(reg, address); |
| 1493 } |
| 1494 |
| 1495 void AssemblerX86::cbw() { |
| 1496 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1497 EmitOperandSizeOverride(); |
| 1498 EmitUint8(0x98); |
| 1499 } |
| 1500 |
| 1501 void AssemblerX86::cwd() { |
| 1502 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1503 EmitOperandSizeOverride(); |
| 1504 EmitUint8(0x99); |
| 1505 } |
| 1506 |
| 1507 void AssemblerX86::cdq() { |
| 1508 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1509 EmitUint8(0x99); |
| 1510 } |
| 1511 |
| 1512 void AssemblerX86::idivl(Register reg) { |
| 1513 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1514 EmitUint8(0xF7); |
| 1515 EmitUint8(0xF8 | reg); |
| 1516 } |
| 1517 |
| 1518 void AssemblerX86::imull(Register dst, Register src) { |
| 1519 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1520 EmitUint8(0x0F); |
| 1521 EmitUint8(0xAF); |
| 1522 EmitOperand(dst, Operand(src)); |
| 1523 } |
| 1524 |
| 1525 void AssemblerX86::imull(Register reg, const Immediate &imm) { |
| 1526 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1527 EmitUint8(0x69); |
| 1528 EmitOperand(reg, Operand(reg)); |
| 1529 EmitImmediate(imm); |
| 1530 } |
| 1531 |
| 1532 void AssemblerX86::imull(Register reg, const Address &address) { |
| 1533 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1534 EmitUint8(0x0F); |
| 1535 EmitUint8(0xAF); |
| 1536 EmitOperand(reg, address); |
| 1537 } |
| 1538 |
| 1539 void AssemblerX86::imull(Register reg) { |
| 1540 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1541 EmitUint8(0xF7); |
| 1542 EmitOperand(5, Operand(reg)); |
| 1543 } |
| 1544 |
| 1545 void AssemblerX86::imull(const Address &address) { |
| 1546 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1547 EmitUint8(0xF7); |
| 1548 EmitOperand(5, address); |
| 1549 } |
| 1550 |
| 1551 void AssemblerX86::mull(Register reg) { |
| 1552 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1553 EmitUint8(0xF7); |
| 1554 EmitOperand(4, Operand(reg)); |
| 1555 } |
| 1556 |
| 1557 void AssemblerX86::mull(const Address &address) { |
| 1558 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1559 EmitUint8(0xF7); |
| 1560 EmitOperand(4, address); |
| 1561 } |
| 1562 |
| 1563 void AssemblerX86::sbb(Type Ty, Register dst, Register src) { |
| 1564 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1565 if (typeWidthInBytes(Ty) == 1) { |
| 1566 EmitUint8(0x1A); |
| 1567 } else if (Ty == IceType_i16) { |
| 1568 EmitOperandSizeOverride(); |
| 1569 EmitUint8(0x1B); |
| 1570 } else { |
| 1571 EmitUint8(0x1B); |
| 1572 } |
| 1573 EmitRegisterOperand(dst, src); |
| 1574 } |
| 1575 |
| 1576 void AssemblerX86::sbb(Type Ty, Register reg, const Immediate &imm) { |
| 1577 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1578 if (typeWidthInBytes(Ty) == 1) { |
| 1579 EmitComplexI8(3, Operand(reg), imm); |
| 1580 return; |
| 1581 } |
| 1582 if (Ty == IceType_i16) |
| 1583 EmitOperandSizeOverride(); |
| 1584 EmitComplex(3, Operand(reg), imm); |
| 1585 } |
| 1586 |
| 1587 void AssemblerX86::sbb(Type Ty, Register dst, const Address &address) { |
| 1588 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1589 if (typeWidthInBytes(Ty) == 1) { |
| 1590 EmitUint8(0x1A); |
| 1591 } else if (Ty == IceType_i16) { |
| 1592 EmitOperandSizeOverride(); |
| 1593 EmitUint8(0x1B); |
| 1594 } else { |
| 1595 EmitUint8(0x1B); |
| 1596 } |
| 1597 EmitOperand(dst, address); |
| 1598 } |
| 1599 |
| 1600 void AssemblerX86::incl(Register reg) { |
| 1601 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1602 EmitUint8(0x40 + reg); |
| 1603 } |
| 1604 |
| 1605 void AssemblerX86::incl(const Address &address) { |
| 1606 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1607 EmitUint8(0xFF); |
| 1608 EmitOperand(0, address); |
| 1609 } |
| 1610 |
| 1611 void AssemblerX86::decl(Register reg) { |
| 1612 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1613 EmitUint8(0x48 + reg); |
| 1614 } |
| 1615 |
| 1616 void AssemblerX86::decl(const Address &address) { |
| 1617 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1618 EmitUint8(0xFF); |
| 1619 EmitOperand(1, address); |
| 1620 } |
| 1621 |
| 1622 void AssemblerX86::shll(Register reg, const Immediate &imm) { |
| 1623 EmitGenericShift(4, reg, imm); |
| 1624 } |
| 1625 |
| 1626 void AssemblerX86::shll(Register operand, Register shifter) { |
| 1627 EmitGenericShift(4, Operand(operand), shifter); |
| 1628 } |
| 1629 |
| 1630 void AssemblerX86::shll(const Address &operand, Register shifter) { |
| 1631 EmitGenericShift(4, Operand(operand), shifter); |
| 1632 } |
| 1633 |
| 1634 void AssemblerX86::shrl(Register reg, const Immediate &imm) { |
| 1635 EmitGenericShift(5, reg, imm); |
| 1636 } |
| 1637 |
| 1638 void AssemblerX86::shrl(Register operand, Register shifter) { |
| 1639 EmitGenericShift(5, Operand(operand), shifter); |
| 1640 } |
| 1641 |
| 1642 void AssemblerX86::sarl(Register reg, const Immediate &imm) { |
| 1643 EmitGenericShift(7, reg, imm); |
| 1644 } |
| 1645 |
| 1646 void AssemblerX86::sarl(Register operand, Register shifter) { |
| 1647 EmitGenericShift(7, Operand(operand), shifter); |
| 1648 } |
| 1649 |
| 1650 void AssemblerX86::sarl(const Address &address, Register shifter) { |
| 1651 EmitGenericShift(7, Operand(address), shifter); |
| 1652 } |
| 1653 |
| 1654 void AssemblerX86::shld(Register dst, Register src) { |
| 1655 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1656 EmitUint8(0x0F); |
| 1657 EmitUint8(0xA5); |
| 1658 EmitRegisterOperand(src, dst); |
| 1659 } |
| 1660 |
| 1661 void AssemblerX86::shld(Register dst, Register src, const Immediate &imm) { |
| 1662 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1663 assert(imm.is_int8()); |
| 1664 EmitUint8(0x0F); |
| 1665 EmitUint8(0xA4); |
| 1666 EmitRegisterOperand(src, dst); |
| 1667 EmitUint8(imm.value() & 0xFF); |
| 1668 } |
| 1669 |
| 1670 void AssemblerX86::shld(const Address &operand, Register src) { |
| 1671 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1672 EmitUint8(0x0F); |
| 1673 EmitUint8(0xA5); |
| 1674 EmitOperand(src, Operand(operand)); |
| 1675 } |
| 1676 |
| 1677 void AssemblerX86::shrd(Register dst, Register src) { |
| 1678 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1679 EmitUint8(0x0F); |
| 1680 EmitUint8(0xAD); |
| 1681 EmitRegisterOperand(src, dst); |
| 1682 } |
| 1683 |
| 1684 void AssemblerX86::shrd(Register dst, Register src, const Immediate &imm) { |
| 1685 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1686 assert(imm.is_int8()); |
| 1687 EmitUint8(0x0F); |
| 1688 EmitUint8(0xAC); |
| 1689 EmitRegisterOperand(src, dst); |
| 1690 EmitUint8(imm.value() & 0xFF); |
| 1691 } |
| 1692 |
| 1693 void AssemblerX86::shrd(const Address &dst, Register src) { |
| 1694 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1695 EmitUint8(0x0F); |
| 1696 EmitUint8(0xAD); |
| 1697 EmitOperand(src, Operand(dst)); |
| 1698 } |
| 1699 |
| 1700 void AssemblerX86::negl(Register reg) { |
| 1701 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1702 EmitUint8(0xF7); |
| 1703 EmitOperand(3, Operand(reg)); |
| 1704 } |
| 1705 |
| 1706 void AssemblerX86::notl(Register reg) { |
| 1707 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1708 EmitUint8(0xF7); |
| 1709 EmitUint8(0xD0 | reg); |
| 1710 } |
| 1711 |
| 1712 void AssemblerX86::bsrl(Register dst, Register src) { |
| 1713 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1714 EmitUint8(0x0F); |
| 1715 EmitUint8(0xBD); |
| 1716 EmitRegisterOperand(dst, src); |
| 1717 } |
| 1718 |
| 1719 void AssemblerX86::bt(Register base, Register offset) { |
| 1720 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1721 EmitUint8(0x0F); |
| 1722 EmitUint8(0xA3); |
| 1723 EmitRegisterOperand(offset, base); |
| 1724 } |
| 1725 |
| 1726 void AssemblerX86::enter(const Immediate &imm) { |
| 1727 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1728 EmitUint8(0xC8); |
| 1729 assert(imm.is_uint16()); |
| 1730 EmitUint8(imm.value() & 0xFF); |
| 1731 EmitUint8((imm.value() >> 8) & 0xFF); |
| 1732 EmitUint8(0x00); |
| 1733 } |
| 1734 |
| 1735 void AssemblerX86::leave() { |
| 1736 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1737 EmitUint8(0xC9); |
| 1738 } |
| 1739 |
| 1740 void AssemblerX86::ret() { |
| 1741 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1742 EmitUint8(0xC3); |
| 1743 } |
| 1744 |
| 1745 void AssemblerX86::ret(const Immediate &imm) { |
| 1746 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1747 EmitUint8(0xC2); |
| 1748 assert(imm.is_uint16()); |
| 1749 EmitUint8(imm.value() & 0xFF); |
| 1750 EmitUint8((imm.value() >> 8) & 0xFF); |
| 1751 } |
| 1752 |
| 1753 void AssemblerX86::nop(int size) { |
| 1754 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1755 // There are nops up to size 15, but for now just provide up to size 8. |
| 1756 assert(0 < size && size <= MAX_NOP_SIZE); |
| 1757 switch (size) { |
| 1758 case 1: |
| 1759 EmitUint8(0x90); |
| 1760 break; |
| 1761 case 2: |
| 1762 EmitUint8(0x66); |
| 1763 EmitUint8(0x90); |
| 1764 break; |
| 1765 case 3: |
| 1766 EmitUint8(0x0F); |
| 1767 EmitUint8(0x1F); |
| 1768 EmitUint8(0x00); |
| 1769 break; |
| 1770 case 4: |
| 1771 EmitUint8(0x0F); |
| 1772 EmitUint8(0x1F); |
| 1773 EmitUint8(0x40); |
| 1774 EmitUint8(0x00); |
| 1775 break; |
| 1776 case 5: |
| 1777 EmitUint8(0x0F); |
| 1778 EmitUint8(0x1F); |
| 1779 EmitUint8(0x44); |
| 1780 EmitUint8(0x00); |
| 1781 EmitUint8(0x00); |
| 1782 break; |
| 1783 case 6: |
| 1784 EmitUint8(0x66); |
| 1785 EmitUint8(0x0F); |
| 1786 EmitUint8(0x1F); |
| 1787 EmitUint8(0x44); |
| 1788 EmitUint8(0x00); |
| 1789 EmitUint8(0x00); |
| 1790 break; |
| 1791 case 7: |
| 1792 EmitUint8(0x0F); |
| 1793 EmitUint8(0x1F); |
| 1794 EmitUint8(0x80); |
| 1795 EmitUint8(0x00); |
| 1796 EmitUint8(0x00); |
| 1797 EmitUint8(0x00); |
| 1798 EmitUint8(0x00); |
| 1799 break; |
| 1800 case 8: |
| 1801 EmitUint8(0x0F); |
| 1802 EmitUint8(0x1F); |
| 1803 EmitUint8(0x84); |
| 1804 EmitUint8(0x00); |
| 1805 EmitUint8(0x00); |
| 1806 EmitUint8(0x00); |
| 1807 EmitUint8(0x00); |
| 1808 EmitUint8(0x00); |
| 1809 break; |
| 1810 default: |
| 1811 llvm_unreachable("UNIMPLEMENTED"); |
| 1812 } |
| 1813 } |
| 1814 |
| 1815 void AssemblerX86::int3() { |
| 1816 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1817 EmitUint8(0xCC); |
| 1818 } |
| 1819 |
| 1820 void AssemblerX86::hlt() { |
| 1821 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1822 EmitUint8(0xF4); |
| 1823 } |
| 1824 |
| 1825 void AssemblerX86::j(Condition condition, Label *label, bool near) { |
| 1826 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1827 if (label->IsBound()) { |
| 1828 static const int kShortSize = 2; |
| 1829 static const int kLongSize = 6; |
| 1830 intptr_t offset = label->Position() - buffer_.Size(); |
| 1831 assert(offset <= 0); |
| 1832 if (Utils::IsInt(8, offset - kShortSize)) { |
| 1833 EmitUint8(0x70 + condition); |
| 1834 EmitUint8((offset - kShortSize) & 0xFF); |
| 1835 } else { |
| 1836 EmitUint8(0x0F); |
| 1837 EmitUint8(0x80 + condition); |
| 1838 EmitInt32(offset - kLongSize); |
| 1839 } |
| 1840 } else if (near) { |
| 1841 EmitUint8(0x70 + condition); |
| 1842 EmitNearLabelLink(label); |
| 1843 } else { |
| 1844 EmitUint8(0x0F); |
| 1845 EmitUint8(0x80 + condition); |
| 1846 EmitLabelLink(label); |
| 1847 } |
| 1848 } |
| 1849 |
| 1850 void AssemblerX86::j(Condition condition, const ConstantRelocatable *label) { |
| 1851 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1852 EmitUint8(0x0F); |
| 1853 EmitUint8(0x80 + condition); |
| 1854 EmitFixup(DirectCallRelocation::create(this, FK_PcRel_4, label)); |
| 1855 EmitInt32(-4); |
| 1856 } |
| 1857 |
| 1858 void AssemblerX86::jmp(Register reg) { |
| 1859 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1860 EmitUint8(0xFF); |
| 1861 EmitRegisterOperand(4, reg); |
| 1862 } |
| 1863 |
| 1864 void AssemblerX86::jmp(Label *label, bool near) { |
| 1865 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1866 if (label->IsBound()) { |
| 1867 static const int kShortSize = 2; |
| 1868 static const int kLongSize = 5; |
| 1869 intptr_t offset = label->Position() - buffer_.Size(); |
| 1870 assert(offset <= 0); |
| 1871 if (Utils::IsInt(8, offset - kShortSize)) { |
| 1872 EmitUint8(0xEB); |
| 1873 EmitUint8((offset - kShortSize) & 0xFF); |
| 1874 } else { |
| 1875 EmitUint8(0xE9); |
| 1876 EmitInt32(offset - kLongSize); |
| 1877 } |
| 1878 } else if (near) { |
| 1879 EmitUint8(0xEB); |
| 1880 EmitNearLabelLink(label); |
| 1881 } else { |
| 1882 EmitUint8(0xE9); |
| 1883 EmitLabelLink(label); |
| 1884 } |
| 1885 } |
| 1886 |
| 1887 void AssemblerX86::jmp(const ConstantRelocatable *label) { |
| 1888 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1889 EmitUint8(0xE9); |
| 1890 EmitFixup(DirectCallRelocation::create(this, FK_PcRel_4, label)); |
| 1891 EmitInt32(-4); |
| 1892 } |
| 1893 |
| 1894 void AssemblerX86::lock() { |
| 1895 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1896 EmitUint8(0xF0); |
| 1897 } |
| 1898 |
| 1899 void AssemblerX86::cmpxchgl(const Address &address, Register reg) { |
| 1900 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1901 EmitUint8(0x0F); |
| 1902 EmitUint8(0xB1); |
| 1903 EmitOperand(reg, address); |
| 1904 } |
| 1905 |
| 1906 void AssemblerX86::Align(intptr_t alignment, intptr_t offset) { |
| 1907 assert(llvm::isPowerOf2_32(alignment)); |
| 1908 intptr_t pos = offset + buffer_.GetPosition(); |
| 1909 intptr_t mod = pos & (alignment - 1); |
| 1910 if (mod == 0) { |
| 1911 return; |
| 1912 } |
| 1913 intptr_t bytes_needed = alignment - mod; |
| 1914 while (bytes_needed > MAX_NOP_SIZE) { |
| 1915 nop(MAX_NOP_SIZE); |
| 1916 bytes_needed -= MAX_NOP_SIZE; |
| 1917 } |
| 1918 if (bytes_needed) { |
| 1919 nop(bytes_needed); |
| 1920 } |
| 1921 assert(((offset + buffer_.GetPosition()) & (alignment - 1)) == 0); |
| 1922 } |
| 1923 |
| 1924 void AssemblerX86::Bind(Label *label) { |
| 1925 intptr_t bound = buffer_.Size(); |
| 1926 assert(!label->IsBound()); // Labels can only be bound once. |
| 1927 while (label->IsLinked()) { |
| 1928 intptr_t position = label->LinkPosition(); |
| 1929 intptr_t next = buffer_.Load<int32_t>(position); |
| 1930 buffer_.Store<int32_t>(position, bound - (position + 4)); |
| 1931 label->position_ = next; |
| 1932 } |
| 1933 while (label->HasNear()) { |
| 1934 intptr_t position = label->NearPosition(); |
| 1935 intptr_t offset = bound - (position + 1); |
| 1936 assert(Utils::IsInt(8, offset)); |
| 1937 buffer_.Store<int8_t>(position, offset); |
| 1938 } |
| 1939 label->BindTo(bound); |
| 1940 } |
| 1941 |
| 1942 void AssemblerX86::EmitOperand(int rm, const Operand &operand) { |
| 1943 assert(rm >= 0 && rm < 8); |
| 1944 const intptr_t length = operand.length_; |
| 1945 assert(length > 0); |
| 1946 // Emit the ModRM byte updated with the given RM value. |
| 1947 assert((operand.encoding_[0] & 0x38) == 0); |
| 1948 EmitUint8(operand.encoding_[0] + (rm << 3)); |
| 1949 if (operand.fixup()) { |
| 1950 EmitFixup(operand.fixup()); |
| 1951 } |
| 1952 // Emit the rest of the encoded operand. |
| 1953 for (intptr_t i = 1; i < length; i++) { |
| 1954 EmitUint8(operand.encoding_[i]); |
| 1955 } |
| 1956 } |
| 1957 |
| 1958 void AssemblerX86::EmitImmediate(const Immediate &imm) { |
| 1959 EmitInt32(imm.value()); |
| 1960 } |
| 1961 |
| 1962 void AssemblerX86::EmitComplexI8(int rm, const Operand &operand, |
| 1963 const Immediate &immediate) { |
| 1964 assert(rm >= 0 && rm < 8); |
| 1965 assert(immediate.is_int8()); |
| 1966 if (operand.IsRegister(EAX)) { |
| 1967 // Use short form if the destination is al. |
| 1968 EmitUint8(0x04 + (rm << 3)); |
| 1969 EmitUint8(immediate.value() & 0xFF); |
| 1970 } else { |
| 1971 // Use sign-extended 8-bit immediate. |
| 1972 EmitUint8(0x80); |
| 1973 EmitOperand(rm, operand); |
| 1974 EmitUint8(immediate.value() & 0xFF); |
| 1975 } |
| 1976 } |
| 1977 |
| 1978 void AssemblerX86::EmitComplex(int rm, const Operand &operand, |
| 1979 const Immediate &immediate) { |
| 1980 assert(rm >= 0 && rm < 8); |
| 1981 if (immediate.is_int8()) { |
| 1982 // Use sign-extended 8-bit immediate. |
| 1983 EmitUint8(0x83); |
| 1984 EmitOperand(rm, operand); |
| 1985 EmitUint8(immediate.value() & 0xFF); |
| 1986 } else if (operand.IsRegister(EAX)) { |
| 1987 // Use short form if the destination is eax. |
| 1988 EmitUint8(0x05 + (rm << 3)); |
| 1989 EmitImmediate(immediate); |
| 1990 } else { |
| 1991 EmitUint8(0x81); |
| 1992 EmitOperand(rm, operand); |
| 1993 EmitImmediate(immediate); |
| 1994 } |
| 1995 } |
| 1996 |
| 1997 void AssemblerX86::EmitLabel(Label *label, intptr_t instruction_size) { |
| 1998 if (label->IsBound()) { |
| 1999 intptr_t offset = label->Position() - buffer_.Size(); |
| 2000 assert(offset <= 0); |
| 2001 EmitInt32(offset - instruction_size); |
| 2002 } else { |
| 2003 EmitLabelLink(label); |
| 2004 } |
| 2005 } |
| 2006 |
| 2007 void AssemblerX86::EmitLabelLink(Label *label) { |
| 2008 assert(!label->IsBound()); |
| 2009 intptr_t position = buffer_.Size(); |
| 2010 EmitInt32(label->position_); |
| 2011 label->LinkTo(position); |
| 2012 } |
| 2013 |
| 2014 void AssemblerX86::EmitNearLabelLink(Label *label) { |
| 2015 assert(!label->IsBound()); |
| 2016 intptr_t position = buffer_.Size(); |
| 2017 EmitUint8(0); |
| 2018 label->NearLinkTo(position); |
| 2019 } |
| 2020 |
| 2021 void AssemblerX86::EmitGenericShift(int rm, Register reg, |
| 2022 const Immediate &imm) { |
| 2023 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2024 assert(imm.is_int8()); |
| 2025 if (imm.value() == 1) { |
| 2026 EmitUint8(0xD1); |
| 2027 EmitOperand(rm, Operand(reg)); |
| 2028 } else { |
| 2029 EmitUint8(0xC1); |
| 2030 EmitOperand(rm, Operand(reg)); |
| 2031 EmitUint8(imm.value() & 0xFF); |
| 2032 } |
| 2033 } |
| 2034 |
| 2035 void AssemblerX86::EmitGenericShift(int rm, const Operand &operand, |
| 2036 Register shifter) { |
| 2037 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2038 assert(shifter == ECX); |
| 2039 EmitUint8(0xD3); |
| 2040 EmitOperand(rm, Operand(operand)); |
| 2041 } |
| 2042 |
| 2043 } // end of namespace x86 |
| 2044 } // end of namespace Ice |
OLD | NEW |