1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "assembler_x86_64.h" 18 19 #include "base/casts.h" 20 #include "entrypoints/quick/quick_entrypoints.h" 21 #include "memory_region.h" 22 #include "thread.h" 23 24 namespace art { 25 namespace x86_64 { 26 27 std::ostream& operator<<(std::ostream& os, const CpuRegister& reg) { 28 return os << reg.AsRegister(); 29 } 30 31 std::ostream& operator<<(std::ostream& os, const XmmRegister& reg) { 32 return os << reg.AsFloatRegister(); 33 } 34 35 std::ostream& operator<<(std::ostream& os, const X87Register& reg) { 36 return os << "ST" << static_cast<int>(reg); 37 } 38 39 void X86_64Assembler::call(CpuRegister reg) { 40 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 41 EmitOptionalRex32(reg); 42 EmitUint8(0xFF); 43 EmitRegisterOperand(2, reg.LowBits()); 44 } 45 46 47 void X86_64Assembler::call(const Address& address) { 48 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 49 EmitOptionalRex32(address); 50 EmitUint8(0xFF); 51 EmitOperand(2, address); 52 } 53 54 55 void X86_64Assembler::call(Label* label) { 56 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 57 EmitUint8(0xE8); 58 static const int kSize = 5; 59 // Offset by one because we already have emitted the opcode. 60 EmitLabel(label, kSize - 1); 61 } 62 63 void X86_64Assembler::pushq(CpuRegister reg) { 64 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 65 EmitOptionalRex32(reg); 66 EmitUint8(0x50 + reg.LowBits()); 67 } 68 69 70 void X86_64Assembler::pushq(const Address& address) { 71 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 72 EmitOptionalRex32(address); 73 EmitUint8(0xFF); 74 EmitOperand(6, address); 75 } 76 77 78 void X86_64Assembler::pushq(const Immediate& imm) { 79 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 80 CHECK(imm.is_int32()); // pushq only supports 32b immediate. 81 if (imm.is_int8()) { 82 EmitUint8(0x6A); 83 EmitUint8(imm.value() & 0xFF); 84 } else { 85 EmitUint8(0x68); 86 EmitImmediate(imm); 87 } 88 } 89 90 91 void X86_64Assembler::popq(CpuRegister reg) { 92 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 93 EmitOptionalRex32(reg); 94 EmitUint8(0x58 + reg.LowBits()); 95 } 96 97 98 void X86_64Assembler::popq(const Address& address) { 99 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 100 EmitOptionalRex32(address); 101 EmitUint8(0x8F); 102 EmitOperand(0, address); 103 } 104 105 106 void X86_64Assembler::movq(CpuRegister dst, const Immediate& imm) { 107 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 108 if (imm.is_int32()) { 109 // 32 bit. Note: sign-extends. 110 EmitRex64(dst); 111 EmitUint8(0xC7); 112 EmitRegisterOperand(0, dst.LowBits()); 113 EmitInt32(static_cast<int32_t>(imm.value())); 114 } else { 115 EmitRex64(dst); 116 EmitUint8(0xB8 + dst.LowBits()); 117 EmitInt64(imm.value()); 118 } 119 } 120 121 122 void X86_64Assembler::movl(CpuRegister dst, const Immediate& imm) { 123 CHECK(imm.is_int32()); 124 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 125 EmitOptionalRex32(dst); 126 EmitUint8(0xB8 + dst.LowBits()); 127 EmitImmediate(imm); 128 } 129 130 131 void X86_64Assembler::movq(const Address& dst, const Immediate& imm) { 132 CHECK(imm.is_int32()); 133 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 134 EmitRex64(dst); 135 EmitUint8(0xC7); 136 EmitOperand(0, dst); 137 EmitImmediate(imm); 138 } 139 140 141 void X86_64Assembler::movq(CpuRegister dst, CpuRegister src) { 142 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 143 // 0x89 is movq r/m64 <- r64, with op1 in r/m and op2 in reg: so reverse EmitRex64 144 EmitRex64(src, dst); 145 EmitUint8(0x89); 146 EmitRegisterOperand(src.LowBits(), dst.LowBits()); 147 } 148 149 150 void X86_64Assembler::movl(CpuRegister dst, CpuRegister src) { 151 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 152 EmitOptionalRex32(dst, src); 153 EmitUint8(0x8B); 154 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 155 } 156 157 158 void X86_64Assembler::movq(CpuRegister dst, const Address& src) { 159 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 160 EmitRex64(dst, src); 161 EmitUint8(0x8B); 162 EmitOperand(dst.LowBits(), src); 163 } 164 165 166 void X86_64Assembler::movl(CpuRegister dst, const Address& src) { 167 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 168 EmitOptionalRex32(dst, src); 169 EmitUint8(0x8B); 170 EmitOperand(dst.LowBits(), src); 171 } 172 173 174 void X86_64Assembler::movq(const Address& dst, CpuRegister src) { 175 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 176 EmitRex64(src, dst); 177 EmitUint8(0x89); 178 EmitOperand(src.LowBits(), dst); 179 } 180 181 182 void X86_64Assembler::movl(const Address& dst, CpuRegister src) { 183 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 184 EmitOptionalRex32(src, dst); 185 EmitUint8(0x89); 186 EmitOperand(src.LowBits(), dst); 187 } 188 189 void X86_64Assembler::movl(const Address& dst, const Immediate& imm) { 190 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 191 EmitOptionalRex32(dst); 192 EmitUint8(0xC7); 193 EmitOperand(0, dst); 194 EmitImmediate(imm); 195 } 196 197 198 void X86_64Assembler::cmov(Condition c, CpuRegister dst, CpuRegister src) { 199 cmov(c, dst, src, true); 200 } 201 202 void X86_64Assembler::cmov(Condition c, CpuRegister dst, CpuRegister src, bool is64bit) { 203 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 204 EmitOptionalRex(false, is64bit, dst.NeedsRex(), false, src.NeedsRex()); 205 EmitUint8(0x0F); 206 EmitUint8(0x40 + c); 207 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 208 } 209 210 211 void X86_64Assembler::movzxb(CpuRegister dst, CpuRegister src) { 212 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 213 EmitOptionalByteRegNormalizingRex32(dst, src); 214 EmitUint8(0x0F); 215 EmitUint8(0xB6); 216 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 217 } 218 219 220 void X86_64Assembler::movzxb(CpuRegister dst, const Address& src) { 221 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 222 // Byte register is only in the source register form, so we don't use 223 // EmitOptionalByteRegNormalizingRex32(dst, src); 224 EmitOptionalRex32(dst, src); 225 EmitUint8(0x0F); 226 EmitUint8(0xB6); 227 EmitOperand(dst.LowBits(), src); 228 } 229 230 231 void X86_64Assembler::movsxb(CpuRegister dst, CpuRegister src) { 232 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 233 EmitOptionalByteRegNormalizingRex32(dst, src); 234 EmitUint8(0x0F); 235 EmitUint8(0xBE); 236 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 237 } 238 239 240 void X86_64Assembler::movsxb(CpuRegister dst, const Address& src) { 241 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 242 // Byte register is only in the source register form, so we don't use 243 // EmitOptionalByteRegNormalizingRex32(dst, src); 244 EmitOptionalRex32(dst, src); 245 EmitUint8(0x0F); 246 EmitUint8(0xBE); 247 EmitOperand(dst.LowBits(), src); 248 } 249 250 251 void X86_64Assembler::movb(CpuRegister /*dst*/, const Address& /*src*/) { 252 LOG(FATAL) << "Use movzxb or movsxb instead."; 253 } 254 255 256 void X86_64Assembler::movb(const Address& dst, CpuRegister src) { 257 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 258 EmitOptionalByteRegNormalizingRex32(src, dst); 259 EmitUint8(0x88); 260 EmitOperand(src.LowBits(), dst); 261 } 262 263 264 void X86_64Assembler::movb(const Address& dst, const Immediate& imm) { 265 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 266 EmitOptionalRex32(dst); 267 EmitUint8(0xC6); 268 EmitOperand(Register::RAX, dst); 269 CHECK(imm.is_int8()); 270 EmitUint8(imm.value() & 0xFF); 271 } 272 273 274 void X86_64Assembler::movzxw(CpuRegister dst, CpuRegister src) { 275 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 276 EmitOptionalRex32(dst, src); 277 EmitUint8(0x0F); 278 EmitUint8(0xB7); 279 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 280 } 281 282 283 void X86_64Assembler::movzxw(CpuRegister dst, const Address& src) { 284 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 285 EmitOptionalRex32(dst, src); 286 EmitUint8(0x0F); 287 EmitUint8(0xB7); 288 EmitOperand(dst.LowBits(), src); 289 } 290 291 292 void X86_64Assembler::movsxw(CpuRegister dst, CpuRegister src) { 293 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 294 EmitOptionalRex32(dst, src); 295 EmitUint8(0x0F); 296 EmitUint8(0xBF); 297 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 298 } 299 300 301 void X86_64Assembler::movsxw(CpuRegister dst, const Address& src) { 302 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 303 EmitOptionalRex32(dst, src); 304 EmitUint8(0x0F); 305 EmitUint8(0xBF); 306 EmitOperand(dst.LowBits(), src); 307 } 308 309 310 void X86_64Assembler::movw(CpuRegister /*dst*/, const Address& /*src*/) { 311 LOG(FATAL) << "Use movzxw or movsxw instead."; 312 } 313 314 315 void X86_64Assembler::movw(const Address& dst, CpuRegister src) { 316 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 317 EmitOperandSizeOverride(); 318 EmitOptionalRex32(src, dst); 319 EmitUint8(0x89); 320 EmitOperand(src.LowBits(), dst); 321 } 322 323 324 void X86_64Assembler::movw(const Address& dst, const Immediate& imm) { 325 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 326 EmitOperandSizeOverride(); 327 EmitOptionalRex32(dst); 328 EmitUint8(0xC7); 329 EmitOperand(Register::RAX, dst); 330 CHECK(imm.is_uint16() || imm.is_int16()); 331 EmitUint8(imm.value() & 0xFF); 332 EmitUint8(imm.value() >> 8); 333 } 334 335 336 void X86_64Assembler::leaq(CpuRegister dst, const Address& src) { 337 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 338 EmitRex64(dst, src); 339 EmitUint8(0x8D); 340 EmitOperand(dst.LowBits(), src); 341 } 342 343 344 void X86_64Assembler::leal(CpuRegister dst, const Address& src) { 345 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 346 EmitOptionalRex32(dst, src); 347 EmitUint8(0x8D); 348 EmitOperand(dst.LowBits(), src); 349 } 350 351 352 void X86_64Assembler::movaps(XmmRegister dst, XmmRegister src) { 353 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 354 EmitOptionalRex32(dst, src); 355 EmitUint8(0x0F); 356 EmitUint8(0x28); 357 EmitXmmRegisterOperand(dst.LowBits(), src); 358 } 359 360 361 void X86_64Assembler::movss(XmmRegister dst, const Address& src) { 362 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 363 EmitUint8(0xF3); 364 EmitOptionalRex32(dst, src); 365 EmitUint8(0x0F); 366 EmitUint8(0x10); 367 EmitOperand(dst.LowBits(), src); 368 } 369 370 371 void X86_64Assembler::movss(const Address& dst, XmmRegister src) { 372 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 373 EmitUint8(0xF3); 374 EmitOptionalRex32(src, dst); 375 EmitUint8(0x0F); 376 EmitUint8(0x11); 377 EmitOperand(src.LowBits(), dst); 378 } 379 380 381 void X86_64Assembler::movss(XmmRegister dst, XmmRegister src) { 382 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 383 EmitUint8(0xF3); 384 EmitOptionalRex32(src, dst); // Movss is MR encoding instead of the usual RM. 385 EmitUint8(0x0F); 386 EmitUint8(0x11); 387 EmitXmmRegisterOperand(src.LowBits(), dst); 388 } 389 390 391 void X86_64Assembler::movsxd(CpuRegister dst, CpuRegister src) { 392 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 393 EmitRex64(dst, src); 394 EmitUint8(0x63); 395 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 396 } 397 398 399 void X86_64Assembler::movsxd(CpuRegister dst, const Address& src) { 400 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 401 EmitRex64(dst, src); 402 EmitUint8(0x63); 403 EmitOperand(dst.LowBits(), src); 404 } 405 406 407 void X86_64Assembler::movd(XmmRegister dst, CpuRegister src) { 408 movd(dst, src, true); 409 } 410 411 void X86_64Assembler::movd(CpuRegister dst, XmmRegister src) { 412 movd(dst, src, true); 413 } 414 415 void X86_64Assembler::movd(XmmRegister dst, CpuRegister src, bool is64bit) { 416 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 417 EmitUint8(0x66); 418 EmitOptionalRex(false, is64bit, dst.NeedsRex(), false, src.NeedsRex()); 419 EmitUint8(0x0F); 420 EmitUint8(0x6E); 421 EmitOperand(dst.LowBits(), Operand(src)); 422 } 423 424 void X86_64Assembler::movd(CpuRegister dst, XmmRegister src, bool is64bit) { 425 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 426 EmitUint8(0x66); 427 EmitOptionalRex(false, is64bit, src.NeedsRex(), false, dst.NeedsRex()); 428 EmitUint8(0x0F); 429 EmitUint8(0x7E); 430 EmitOperand(src.LowBits(), Operand(dst)); 431 } 432 433 434 void X86_64Assembler::addss(XmmRegister dst, XmmRegister src) { 435 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 436 EmitUint8(0xF3); 437 EmitOptionalRex32(dst, src); 438 EmitUint8(0x0F); 439 EmitUint8(0x58); 440 EmitXmmRegisterOperand(dst.LowBits(), src); 441 } 442 443 444 void X86_64Assembler::addss(XmmRegister dst, const Address& src) { 445 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 446 EmitUint8(0xF3); 447 EmitOptionalRex32(dst, src); 448 EmitUint8(0x0F); 449 EmitUint8(0x58); 450 EmitOperand(dst.LowBits(), src); 451 } 452 453 454 void X86_64Assembler::subss(XmmRegister dst, XmmRegister src) { 455 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 456 EmitUint8(0xF3); 457 EmitOptionalRex32(dst, src); 458 EmitUint8(0x0F); 459 EmitUint8(0x5C); 460 EmitXmmRegisterOperand(dst.LowBits(), src); 461 } 462 463 464 void X86_64Assembler::subss(XmmRegister dst, const Address& src) { 465 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 466 EmitUint8(0xF3); 467 EmitOptionalRex32(dst, src); 468 EmitUint8(0x0F); 469 EmitUint8(0x5C); 470 EmitOperand(dst.LowBits(), src); 471 } 472 473 474 void X86_64Assembler::mulss(XmmRegister dst, XmmRegister src) { 475 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 476 EmitUint8(0xF3); 477 EmitOptionalRex32(dst, src); 478 EmitUint8(0x0F); 479 EmitUint8(0x59); 480 EmitXmmRegisterOperand(dst.LowBits(), src); 481 } 482 483 484 void X86_64Assembler::mulss(XmmRegister dst, const Address& src) { 485 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 486 EmitUint8(0xF3); 487 EmitOptionalRex32(dst, src); 488 EmitUint8(0x0F); 489 EmitUint8(0x59); 490 EmitOperand(dst.LowBits(), src); 491 } 492 493 494 void X86_64Assembler::divss(XmmRegister dst, XmmRegister src) { 495 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 496 EmitUint8(0xF3); 497 EmitOptionalRex32(dst, src); 498 EmitUint8(0x0F); 499 EmitUint8(0x5E); 500 EmitXmmRegisterOperand(dst.LowBits(), src); 501 } 502 503 504 void X86_64Assembler::divss(XmmRegister dst, const Address& src) { 505 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 506 EmitUint8(0xF3); 507 EmitOptionalRex32(dst, src); 508 EmitUint8(0x0F); 509 EmitUint8(0x5E); 510 EmitOperand(dst.LowBits(), src); 511 } 512 513 514 void X86_64Assembler::flds(const Address& src) { 515 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 516 EmitUint8(0xD9); 517 EmitOperand(0, src); 518 } 519 520 521 void X86_64Assembler::fsts(const Address& dst) { 522 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 523 EmitUint8(0xD9); 524 EmitOperand(2, dst); 525 } 526 527 528 void X86_64Assembler::fstps(const Address& dst) { 529 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 530 EmitUint8(0xD9); 531 EmitOperand(3, dst); 532 } 533 534 535 void X86_64Assembler::movsd(XmmRegister dst, const Address& src) { 536 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 537 EmitUint8(0xF2); 538 EmitOptionalRex32(dst, src); 539 EmitUint8(0x0F); 540 EmitUint8(0x10); 541 EmitOperand(dst.LowBits(), src); 542 } 543 544 545 void X86_64Assembler::movsd(const Address& dst, XmmRegister src) { 546 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 547 EmitUint8(0xF2); 548 EmitOptionalRex32(src, dst); 549 EmitUint8(0x0F); 550 EmitUint8(0x11); 551 EmitOperand(src.LowBits(), dst); 552 } 553 554 555 void X86_64Assembler::movsd(XmmRegister dst, XmmRegister src) { 556 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 557 EmitUint8(0xF2); 558 EmitOptionalRex32(src, dst); // Movsd is MR encoding instead of the usual RM. 559 EmitUint8(0x0F); 560 EmitUint8(0x11); 561 EmitXmmRegisterOperand(src.LowBits(), dst); 562 } 563 564 565 void X86_64Assembler::addsd(XmmRegister dst, XmmRegister src) { 566 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 567 EmitUint8(0xF2); 568 EmitOptionalRex32(dst, src); 569 EmitUint8(0x0F); 570 EmitUint8(0x58); 571 EmitXmmRegisterOperand(dst.LowBits(), src); 572 } 573 574 575 void X86_64Assembler::addsd(XmmRegister dst, const Address& src) { 576 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 577 EmitUint8(0xF2); 578 EmitOptionalRex32(dst, src); 579 EmitUint8(0x0F); 580 EmitUint8(0x58); 581 EmitOperand(dst.LowBits(), src); 582 } 583 584 585 void X86_64Assembler::subsd(XmmRegister dst, XmmRegister src) { 586 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 587 EmitUint8(0xF2); 588 EmitOptionalRex32(dst, src); 589 EmitUint8(0x0F); 590 EmitUint8(0x5C); 591 EmitXmmRegisterOperand(dst.LowBits(), src); 592 } 593 594 595 void X86_64Assembler::subsd(XmmRegister dst, const Address& src) { 596 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 597 EmitUint8(0xF2); 598 EmitOptionalRex32(dst, src); 599 EmitUint8(0x0F); 600 EmitUint8(0x5C); 601 EmitOperand(dst.LowBits(), src); 602 } 603 604 605 void X86_64Assembler::mulsd(XmmRegister dst, XmmRegister src) { 606 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 607 EmitUint8(0xF2); 608 EmitOptionalRex32(dst, src); 609 EmitUint8(0x0F); 610 EmitUint8(0x59); 611 EmitXmmRegisterOperand(dst.LowBits(), src); 612 } 613 614 615 void X86_64Assembler::mulsd(XmmRegister dst, const Address& src) { 616 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 617 EmitUint8(0xF2); 618 EmitOptionalRex32(dst, src); 619 EmitUint8(0x0F); 620 EmitUint8(0x59); 621 EmitOperand(dst.LowBits(), src); 622 } 623 624 625 void X86_64Assembler::divsd(XmmRegister dst, XmmRegister src) { 626 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 627 EmitUint8(0xF2); 628 EmitOptionalRex32(dst, src); 629 EmitUint8(0x0F); 630 EmitUint8(0x5E); 631 EmitXmmRegisterOperand(dst.LowBits(), src); 632 } 633 634 635 void X86_64Assembler::divsd(XmmRegister dst, const Address& src) { 636 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 637 EmitUint8(0xF2); 638 EmitOptionalRex32(dst, src); 639 EmitUint8(0x0F); 640 EmitUint8(0x5E); 641 EmitOperand(dst.LowBits(), src); 642 } 643 644 645 void X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src) { 646 cvtsi2ss(dst, src, false); 647 } 648 649 650 void X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src, bool is64bit) { 651 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 652 EmitUint8(0xF3); 653 if (is64bit) { 654 // Emit a REX.W prefix if the operand size is 64 bits. 655 EmitRex64(dst, src); 656 } else { 657 EmitOptionalRex32(dst, src); 658 } 659 EmitUint8(0x0F); 660 EmitUint8(0x2A); 661 EmitOperand(dst.LowBits(), Operand(src)); 662 } 663 664 665 void X86_64Assembler::cvtsi2ss(XmmRegister dst, const Address& src, bool is64bit) { 666 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 667 EmitUint8(0xF3); 668 if (is64bit) { 669 // Emit a REX.W prefix if the operand size is 64 bits. 670 EmitRex64(dst, src); 671 } else { 672 EmitOptionalRex32(dst, src); 673 } 674 EmitUint8(0x0F); 675 EmitUint8(0x2A); 676 EmitOperand(dst.LowBits(), src); 677 } 678 679 680 void X86_64Assembler::cvtsi2sd(XmmRegister dst, CpuRegister src) { 681 cvtsi2sd(dst, src, false); 682 } 683 684 685 void X86_64Assembler::cvtsi2sd(XmmRegister dst, CpuRegister src, bool is64bit) { 686 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 687 EmitUint8(0xF2); 688 if (is64bit) { 689 // Emit a REX.W prefix if the operand size is 64 bits. 690 EmitRex64(dst, src); 691 } else { 692 EmitOptionalRex32(dst, src); 693 } 694 EmitUint8(0x0F); 695 EmitUint8(0x2A); 696 EmitOperand(dst.LowBits(), Operand(src)); 697 } 698 699 700 void X86_64Assembler::cvtsi2sd(XmmRegister dst, const Address& src, bool is64bit) { 701 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 702 EmitUint8(0xF2); 703 if (is64bit) { 704 // Emit a REX.W prefix if the operand size is 64 bits. 705 EmitRex64(dst, src); 706 } else { 707 EmitOptionalRex32(dst, src); 708 } 709 EmitUint8(0x0F); 710 EmitUint8(0x2A); 711 EmitOperand(dst.LowBits(), src); 712 } 713 714 715 void X86_64Assembler::cvtss2si(CpuRegister dst, XmmRegister src) { 716 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 717 EmitUint8(0xF3); 718 EmitOptionalRex32(dst, src); 719 EmitUint8(0x0F); 720 EmitUint8(0x2D); 721 EmitXmmRegisterOperand(dst.LowBits(), src); 722 } 723 724 725 void X86_64Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) { 726 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 727 EmitUint8(0xF3); 728 EmitOptionalRex32(dst, src); 729 EmitUint8(0x0F); 730 EmitUint8(0x5A); 731 EmitXmmRegisterOperand(dst.LowBits(), src); 732 } 733 734 735 void X86_64Assembler::cvtss2sd(XmmRegister dst, const Address& src) { 736 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 737 EmitUint8(0xF3); 738 EmitOptionalRex32(dst, src); 739 EmitUint8(0x0F); 740 EmitUint8(0x5A); 741 EmitOperand(dst.LowBits(), src); 742 } 743 744 745 void X86_64Assembler::cvtsd2si(CpuRegister dst, XmmRegister src) { 746 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 747 EmitUint8(0xF2); 748 EmitOptionalRex32(dst, src); 749 EmitUint8(0x0F); 750 EmitUint8(0x2D); 751 EmitXmmRegisterOperand(dst.LowBits(), src); 752 } 753 754 755 void X86_64Assembler::cvttss2si(CpuRegister dst, XmmRegister src) { 756 cvttss2si(dst, src, false); 757 } 758 759 760 void X86_64Assembler::cvttss2si(CpuRegister dst, XmmRegister src, bool is64bit) { 761 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 762 EmitUint8(0xF3); 763 if (is64bit) { 764 // Emit a REX.W prefix if the operand size is 64 bits. 765 EmitRex64(dst, src); 766 } else { 767 EmitOptionalRex32(dst, src); 768 } 769 EmitUint8(0x0F); 770 EmitUint8(0x2C); 771 EmitXmmRegisterOperand(dst.LowBits(), src); 772 } 773 774 775 void X86_64Assembler::cvttsd2si(CpuRegister dst, XmmRegister src) { 776 cvttsd2si(dst, src, false); 777 } 778 779 780 void X86_64Assembler::cvttsd2si(CpuRegister dst, XmmRegister src, bool is64bit) { 781 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 782 EmitUint8(0xF2); 783 if (is64bit) { 784 // Emit a REX.W prefix if the operand size is 64 bits. 785 EmitRex64(dst, src); 786 } else { 787 EmitOptionalRex32(dst, src); 788 } 789 EmitUint8(0x0F); 790 EmitUint8(0x2C); 791 EmitXmmRegisterOperand(dst.LowBits(), src); 792 } 793 794 795 void X86_64Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) { 796 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 797 EmitUint8(0xF2); 798 EmitOptionalRex32(dst, src); 799 EmitUint8(0x0F); 800 EmitUint8(0x5A); 801 EmitXmmRegisterOperand(dst.LowBits(), src); 802 } 803 804 805 void X86_64Assembler::cvtsd2ss(XmmRegister dst, const Address& src) { 806 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 807 EmitUint8(0xF2); 808 EmitOptionalRex32(dst, src); 809 EmitUint8(0x0F); 810 EmitUint8(0x5A); 811 EmitOperand(dst.LowBits(), src); 812 } 813 814 815 void X86_64Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) { 816 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 817 EmitUint8(0xF3); 818 EmitOptionalRex32(dst, src); 819 EmitUint8(0x0F); 820 EmitUint8(0xE6); 821 EmitXmmRegisterOperand(dst.LowBits(), src); 822 } 823 824 825 void X86_64Assembler::comiss(XmmRegister a, XmmRegister b) { 826 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 827 EmitOptionalRex32(a, b); 828 EmitUint8(0x0F); 829 EmitUint8(0x2F); 830 EmitXmmRegisterOperand(a.LowBits(), b); 831 } 832 833 834 void X86_64Assembler::comiss(XmmRegister a, const Address& b) { 835 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 836 EmitOptionalRex32(a, b); 837 EmitUint8(0x0F); 838 EmitUint8(0x2F); 839 EmitOperand(a.LowBits(), b); 840 } 841 842 843 void X86_64Assembler::comisd(XmmRegister a, XmmRegister b) { 844 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 845 EmitUint8(0x66); 846 EmitOptionalRex32(a, b); 847 EmitUint8(0x0F); 848 EmitUint8(0x2F); 849 EmitXmmRegisterOperand(a.LowBits(), b); 850 } 851 852 853 void X86_64Assembler::comisd(XmmRegister a, const Address& b) { 854 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 855 EmitUint8(0x66); 856 EmitOptionalRex32(a, b); 857 EmitUint8(0x0F); 858 EmitUint8(0x2F); 859 EmitOperand(a.LowBits(), b); 860 } 861 862 863 void X86_64Assembler::ucomiss(XmmRegister a, XmmRegister b) { 864 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 865 EmitOptionalRex32(a, b); 866 EmitUint8(0x0F); 867 EmitUint8(0x2E); 868 EmitXmmRegisterOperand(a.LowBits(), b); 869 } 870 871 872 void X86_64Assembler::ucomiss(XmmRegister a, const Address& b) { 873 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 874 EmitOptionalRex32(a, b); 875 EmitUint8(0x0F); 876 EmitUint8(0x2E); 877 EmitOperand(a.LowBits(), b); 878 } 879 880 881 void X86_64Assembler::ucomisd(XmmRegister a, XmmRegister b) { 882 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 883 EmitUint8(0x66); 884 EmitOptionalRex32(a, b); 885 EmitUint8(0x0F); 886 EmitUint8(0x2E); 887 EmitXmmRegisterOperand(a.LowBits(), b); 888 } 889 890 891 void X86_64Assembler::ucomisd(XmmRegister a, const Address& b) { 892 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 893 EmitUint8(0x66); 894 EmitOptionalRex32(a, b); 895 EmitUint8(0x0F); 896 EmitUint8(0x2E); 897 EmitOperand(a.LowBits(), b); 898 } 899 900 901 void X86_64Assembler::roundsd(XmmRegister dst, XmmRegister src, const Immediate& imm) { 902 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 903 EmitUint8(0x66); 904 EmitOptionalRex32(dst, src); 905 EmitUint8(0x0F); 906 EmitUint8(0x3A); 907 EmitUint8(0x0B); 908 EmitXmmRegisterOperand(dst.LowBits(), src); 909 EmitUint8(imm.value()); 910 } 911 912 913 void X86_64Assembler::roundss(XmmRegister dst, XmmRegister src, const Immediate& imm) { 914 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 915 EmitUint8(0x66); 916 EmitOptionalRex32(dst, src); 917 EmitUint8(0x0F); 918 EmitUint8(0x3A); 919 EmitUint8(0x0A); 920 EmitXmmRegisterOperand(dst.LowBits(), src); 921 EmitUint8(imm.value()); 922 } 923 924 925 void X86_64Assembler::sqrtsd(XmmRegister dst, XmmRegister src) { 926 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 927 EmitUint8(0xF2); 928 EmitOptionalRex32(dst, src); 929 EmitUint8(0x0F); 930 EmitUint8(0x51); 931 EmitXmmRegisterOperand(dst.LowBits(), src); 932 } 933 934 935 void X86_64Assembler::sqrtss(XmmRegister dst, XmmRegister src) { 936 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 937 EmitUint8(0xF3); 938 EmitOptionalRex32(dst, src); 939 EmitUint8(0x0F); 940 EmitUint8(0x51); 941 EmitXmmRegisterOperand(dst.LowBits(), src); 942 } 943 944 945 void X86_64Assembler::xorpd(XmmRegister dst, const Address& src) { 946 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 947 EmitUint8(0x66); 948 EmitOptionalRex32(dst, src); 949 EmitUint8(0x0F); 950 EmitUint8(0x57); 951 EmitOperand(dst.LowBits(), src); 952 } 953 954 955 void X86_64Assembler::xorpd(XmmRegister dst, XmmRegister src) { 956 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 957 EmitUint8(0x66); 958 EmitOptionalRex32(dst, src); 959 EmitUint8(0x0F); 960 EmitUint8(0x57); 961 EmitXmmRegisterOperand(dst.LowBits(), src); 962 } 963 964 965 void X86_64Assembler::xorps(XmmRegister dst, const Address& src) { 966 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 967 EmitOptionalRex32(dst, src); 968 EmitUint8(0x0F); 969 EmitUint8(0x57); 970 EmitOperand(dst.LowBits(), src); 971 } 972 973 974 void X86_64Assembler::xorps(XmmRegister dst, XmmRegister src) { 975 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 976 EmitOptionalRex32(dst, src); 977 EmitUint8(0x0F); 978 EmitUint8(0x57); 979 EmitXmmRegisterOperand(dst.LowBits(), src); 980 } 981 982 983 void X86_64Assembler::andpd(XmmRegister dst, const Address& src) { 984 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 985 EmitUint8(0x66); 986 EmitOptionalRex32(dst, src); 987 EmitUint8(0x0F); 988 EmitUint8(0x54); 989 EmitOperand(dst.LowBits(), src); 990 } 991 992 void X86_64Assembler::andpd(XmmRegister dst, XmmRegister src) { 993 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 994 EmitUint8(0x66); 995 EmitOptionalRex32(dst, src); 996 EmitUint8(0x0F); 997 EmitUint8(0x54); 998 EmitXmmRegisterOperand(dst.LowBits(), src); 999 } 1000 1001 void X86_64Assembler::andps(XmmRegister dst, XmmRegister src) { 1002 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1003 EmitOptionalRex32(dst, src); 1004 EmitUint8(0x0F); 1005 EmitUint8(0x54); 1006 EmitXmmRegisterOperand(dst.LowBits(), src); 1007 } 1008 1009 void X86_64Assembler::orpd(XmmRegister dst, XmmRegister src) { 1010 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1011 EmitUint8(0x66); 1012 EmitOptionalRex32(dst, src); 1013 EmitUint8(0x0F); 1014 EmitUint8(0x56); 1015 EmitXmmRegisterOperand(dst.LowBits(), src); 1016 } 1017 1018 void X86_64Assembler::orps(XmmRegister dst, XmmRegister src) { 1019 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1020 EmitOptionalRex32(dst, src); 1021 EmitUint8(0x0F); 1022 EmitUint8(0x56); 1023 EmitXmmRegisterOperand(dst.LowBits(), src); 1024 } 1025 1026 void X86_64Assembler::fldl(const Address& src) { 1027 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1028 EmitUint8(0xDD); 1029 EmitOperand(0, src); 1030 } 1031 1032 1033 void X86_64Assembler::fstl(const Address& dst) { 1034 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1035 EmitUint8(0xDD); 1036 EmitOperand(2, dst); 1037 } 1038 1039 1040 void X86_64Assembler::fstpl(const Address& dst) { 1041 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1042 EmitUint8(0xDD); 1043 EmitOperand(3, dst); 1044 } 1045 1046 1047 void X86_64Assembler::fstsw() { 1048 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1049 EmitUint8(0x9B); 1050 EmitUint8(0xDF); 1051 EmitUint8(0xE0); 1052 } 1053 1054 1055 void X86_64Assembler::fnstcw(const Address& dst) { 1056 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1057 EmitUint8(0xD9); 1058 EmitOperand(7, dst); 1059 } 1060 1061 1062 void X86_64Assembler::fldcw(const Address& src) { 1063 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1064 EmitUint8(0xD9); 1065 EmitOperand(5, src); 1066 } 1067 1068 1069 void X86_64Assembler::fistpl(const Address& dst) { 1070 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1071 EmitUint8(0xDF); 1072 EmitOperand(7, dst); 1073 } 1074 1075 1076 void X86_64Assembler::fistps(const Address& dst) { 1077 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1078 EmitUint8(0xDB); 1079 EmitOperand(3, dst); 1080 } 1081 1082 1083 void X86_64Assembler::fildl(const Address& src) { 1084 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1085 EmitUint8(0xDF); 1086 EmitOperand(5, src); 1087 } 1088 1089 1090 void X86_64Assembler::filds(const Address& src) { 1091 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1092 EmitUint8(0xDB); 1093 EmitOperand(0, src); 1094 } 1095 1096 1097 void X86_64Assembler::fincstp() { 1098 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1099 EmitUint8(0xD9); 1100 EmitUint8(0xF7); 1101 } 1102 1103 1104 void X86_64Assembler::ffree(const Immediate& index) { 1105 CHECK_LT(index.value(), 7); 1106 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1107 EmitUint8(0xDD); 1108 EmitUint8(0xC0 + index.value()); 1109 } 1110 1111 1112 void X86_64Assembler::fsin() { 1113 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1114 EmitUint8(0xD9); 1115 EmitUint8(0xFE); 1116 } 1117 1118 1119 void X86_64Assembler::fcos() { 1120 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1121 EmitUint8(0xD9); 1122 EmitUint8(0xFF); 1123 } 1124 1125 1126 void X86_64Assembler::fptan() { 1127 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1128 EmitUint8(0xD9); 1129 EmitUint8(0xF2); 1130 } 1131 1132 void X86_64Assembler::fucompp() { 1133 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1134 EmitUint8(0xDA); 1135 EmitUint8(0xE9); 1136 } 1137 1138 1139 void X86_64Assembler::fprem() { 1140 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1141 EmitUint8(0xD9); 1142 EmitUint8(0xF8); 1143 } 1144 1145 1146 void X86_64Assembler::xchgl(CpuRegister dst, CpuRegister src) { 1147 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1148 // There is a short version for rax. 1149 // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't 1150 // work. 1151 const bool src_rax = src.AsRegister() == RAX; 1152 const bool dst_rax = dst.AsRegister() == RAX; 1153 if (src_rax || dst_rax) { 1154 EmitOptionalRex32(src_rax ? dst : src); 1155 EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits())); 1156 return; 1157 } 1158 1159 // General case. 1160 EmitOptionalRex32(src, dst); 1161 EmitUint8(0x87); 1162 EmitRegisterOperand(src.LowBits(), dst.LowBits()); 1163 } 1164 1165 1166 void X86_64Assembler::xchgq(CpuRegister dst, CpuRegister src) { 1167 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1168 // There is a short version for rax. 1169 // It's a bit awkward, as CpuRegister has a const field, so assignment and thus swapping doesn't 1170 // work. 1171 const bool src_rax = src.AsRegister() == RAX; 1172 const bool dst_rax = dst.AsRegister() == RAX; 1173 if (src_rax || dst_rax) { 1174 // If src == target, emit a nop instead. 1175 if (src_rax && dst_rax) { 1176 EmitUint8(0x90); 1177 } else { 1178 EmitRex64(src_rax ? dst : src); 1179 EmitUint8(0x90 + (src_rax ? dst.LowBits() : src.LowBits())); 1180 } 1181 return; 1182 } 1183 1184 // General case. 1185 EmitRex64(src, dst); 1186 EmitUint8(0x87); 1187 EmitRegisterOperand(src.LowBits(), dst.LowBits()); 1188 } 1189 1190 1191 void X86_64Assembler::xchgl(CpuRegister reg, const Address& address) { 1192 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1193 EmitOptionalRex32(reg, address); 1194 EmitUint8(0x87); 1195 EmitOperand(reg.LowBits(), address); 1196 } 1197 1198 1199 void X86_64Assembler::cmpw(const Address& address, const Immediate& imm) { 1200 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1201 EmitOptionalRex32(address); 1202 EmitUint8(0x66); 1203 EmitComplex(7, address, imm); 1204 } 1205 1206 1207 void X86_64Assembler::cmpl(CpuRegister reg, const Immediate& imm) { 1208 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1209 EmitOptionalRex32(reg); 1210 EmitComplex(7, Operand(reg), imm); 1211 } 1212 1213 1214 void X86_64Assembler::cmpl(CpuRegister reg0, CpuRegister reg1) { 1215 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1216 EmitOptionalRex32(reg0, reg1); 1217 EmitUint8(0x3B); 1218 EmitOperand(reg0.LowBits(), Operand(reg1)); 1219 } 1220 1221 1222 void X86_64Assembler::cmpl(CpuRegister reg, const Address& address) { 1223 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1224 EmitOptionalRex32(reg, address); 1225 EmitUint8(0x3B); 1226 EmitOperand(reg.LowBits(), address); 1227 } 1228 1229 1230 void X86_64Assembler::cmpl(const Address& address, CpuRegister reg) { 1231 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1232 EmitOptionalRex32(reg, address); 1233 EmitUint8(0x39); 1234 EmitOperand(reg.LowBits(), address); 1235 } 1236 1237 1238 void X86_64Assembler::cmpl(const Address& address, const Immediate& imm) { 1239 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1240 EmitOptionalRex32(address); 1241 EmitComplex(7, address, imm); 1242 } 1243 1244 1245 void X86_64Assembler::cmpq(CpuRegister reg0, CpuRegister reg1) { 1246 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1247 EmitRex64(reg0, reg1); 1248 EmitUint8(0x3B); 1249 EmitOperand(reg0.LowBits(), Operand(reg1)); 1250 } 1251 1252 1253 void X86_64Assembler::cmpq(CpuRegister reg, const Immediate& imm) { 1254 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1255 CHECK(imm.is_int32()); // cmpq only supports 32b immediate. 1256 EmitRex64(reg); 1257 EmitComplex(7, Operand(reg), imm); 1258 } 1259 1260 1261 void X86_64Assembler::cmpq(CpuRegister reg, const Address& address) { 1262 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1263 EmitRex64(reg, address); 1264 EmitUint8(0x3B); 1265 EmitOperand(reg.LowBits(), address); 1266 } 1267 1268 1269 void X86_64Assembler::cmpq(const Address& address, const Immediate& imm) { 1270 CHECK(imm.is_int32()); // cmpq only supports 32b immediate. 1271 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1272 EmitRex64(address); 1273 EmitComplex(7, address, imm); 1274 } 1275 1276 1277 void X86_64Assembler::addl(CpuRegister dst, CpuRegister src) { 1278 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1279 EmitOptionalRex32(dst, src); 1280 EmitUint8(0x03); 1281 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 1282 } 1283 1284 1285 void X86_64Assembler::addl(CpuRegister reg, const Address& address) { 1286 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1287 EmitOptionalRex32(reg, address); 1288 EmitUint8(0x03); 1289 EmitOperand(reg.LowBits(), address); 1290 } 1291 1292 1293 void X86_64Assembler::testl(CpuRegister reg1, CpuRegister reg2) { 1294 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1295 EmitOptionalRex32(reg1, reg2); 1296 EmitUint8(0x85); 1297 EmitRegisterOperand(reg1.LowBits(), reg2.LowBits()); 1298 } 1299 1300 1301 void X86_64Assembler::testl(CpuRegister reg, const Address& address) { 1302 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1303 EmitOptionalRex32(reg, address); 1304 EmitUint8(0x85); 1305 EmitOperand(reg.LowBits(), address); 1306 } 1307 1308 1309 void X86_64Assembler::testl(CpuRegister reg, const Immediate& immediate) { 1310 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1311 // For registers that have a byte variant (RAX, RBX, RCX, and RDX) 1312 // we only test the byte CpuRegister to keep the encoding short. 1313 if (immediate.is_uint8() && reg.AsRegister() < 4) { 1314 // Use zero-extended 8-bit immediate. 1315 if (reg.AsRegister() == RAX) { 1316 EmitUint8(0xA8); 1317 } else { 1318 EmitUint8(0xF6); 1319 EmitUint8(0xC0 + reg.AsRegister()); 1320 } 1321 EmitUint8(immediate.value() & 0xFF); 1322 } else if (reg.AsRegister() == RAX) { 1323 // Use short form if the destination is RAX. 1324 EmitUint8(0xA9); 1325 EmitImmediate(immediate); 1326 } else { 1327 EmitOptionalRex32(reg); 1328 EmitUint8(0xF7); 1329 EmitOperand(0, Operand(reg)); 1330 EmitImmediate(immediate); 1331 } 1332 } 1333 1334 1335 void X86_64Assembler::testq(CpuRegister reg1, CpuRegister reg2) { 1336 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1337 EmitRex64(reg1, reg2); 1338 EmitUint8(0x85); 1339 EmitRegisterOperand(reg1.LowBits(), reg2.LowBits()); 1340 } 1341 1342 1343 void X86_64Assembler::testq(CpuRegister reg, const Address& address) { 1344 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1345 EmitRex64(reg, address); 1346 EmitUint8(0x85); 1347 EmitOperand(reg.LowBits(), address); 1348 } 1349 1350 1351 void X86_64Assembler::andl(CpuRegister dst, CpuRegister src) { 1352 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1353 EmitOptionalRex32(dst, src); 1354 EmitUint8(0x23); 1355 EmitOperand(dst.LowBits(), Operand(src)); 1356 } 1357 1358 1359 void X86_64Assembler::andl(CpuRegister reg, const Address& address) { 1360 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1361 EmitOptionalRex32(reg, address); 1362 EmitUint8(0x23); 1363 EmitOperand(reg.LowBits(), address); 1364 } 1365 1366 1367 void X86_64Assembler::andl(CpuRegister dst, const Immediate& imm) { 1368 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1369 EmitOptionalRex32(dst); 1370 EmitComplex(4, Operand(dst), imm); 1371 } 1372 1373 1374 void X86_64Assembler::andq(CpuRegister reg, const Immediate& imm) { 1375 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1376 CHECK(imm.is_int32()); // andq only supports 32b immediate. 1377 EmitRex64(reg); 1378 EmitComplex(4, Operand(reg), imm); 1379 } 1380 1381 1382 void X86_64Assembler::andq(CpuRegister dst, CpuRegister src) { 1383 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1384 EmitRex64(dst, src); 1385 EmitUint8(0x23); 1386 EmitOperand(dst.LowBits(), Operand(src)); 1387 } 1388 1389 1390 void X86_64Assembler::andq(CpuRegister dst, const Address& src) { 1391 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1392 EmitRex64(dst, src); 1393 EmitUint8(0x23); 1394 EmitOperand(dst.LowBits(), src); 1395 } 1396 1397 1398 void X86_64Assembler::orl(CpuRegister dst, CpuRegister src) { 1399 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1400 EmitOptionalRex32(dst, src); 1401 EmitUint8(0x0B); 1402 EmitOperand(dst.LowBits(), Operand(src)); 1403 } 1404 1405 1406 void X86_64Assembler::orl(CpuRegister reg, const Address& address) { 1407 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1408 EmitOptionalRex32(reg, address); 1409 EmitUint8(0x0B); 1410 EmitOperand(reg.LowBits(), address); 1411 } 1412 1413 1414 void X86_64Assembler::orl(CpuRegister dst, const Immediate& imm) { 1415 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1416 EmitOptionalRex32(dst); 1417 EmitComplex(1, Operand(dst), imm); 1418 } 1419 1420 1421 void X86_64Assembler::orq(CpuRegister dst, const Immediate& imm) { 1422 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1423 CHECK(imm.is_int32()); // orq only supports 32b immediate. 1424 EmitRex64(dst); 1425 EmitComplex(1, Operand(dst), imm); 1426 } 1427 1428 1429 void X86_64Assembler::orq(CpuRegister dst, CpuRegister src) { 1430 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1431 EmitRex64(dst, src); 1432 EmitUint8(0x0B); 1433 EmitOperand(dst.LowBits(), Operand(src)); 1434 } 1435 1436 1437 void X86_64Assembler::orq(CpuRegister dst, const Address& src) { 1438 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1439 EmitRex64(dst, src); 1440 EmitUint8(0x0B); 1441 EmitOperand(dst.LowBits(), src); 1442 } 1443 1444 1445 void X86_64Assembler::xorl(CpuRegister dst, CpuRegister src) { 1446 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1447 EmitOptionalRex32(dst, src); 1448 EmitUint8(0x33); 1449 EmitOperand(dst.LowBits(), Operand(src)); 1450 } 1451 1452 1453 void X86_64Assembler::xorl(CpuRegister reg, const Address& address) { 1454 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1455 EmitOptionalRex32(reg, address); 1456 EmitUint8(0x33); 1457 EmitOperand(reg.LowBits(), address); 1458 } 1459 1460 1461 void X86_64Assembler::xorl(CpuRegister dst, const Immediate& imm) { 1462 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1463 EmitOptionalRex32(dst); 1464 EmitComplex(6, Operand(dst), imm); 1465 } 1466 1467 1468 void X86_64Assembler::xorq(CpuRegister dst, CpuRegister src) { 1469 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1470 EmitRex64(dst, src); 1471 EmitUint8(0x33); 1472 EmitOperand(dst.LowBits(), Operand(src)); 1473 } 1474 1475 1476 void X86_64Assembler::xorq(CpuRegister dst, const Immediate& imm) { 1477 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1478 CHECK(imm.is_int32()); // xorq only supports 32b immediate. 1479 EmitRex64(dst); 1480 EmitComplex(6, Operand(dst), imm); 1481 } 1482 1483 void X86_64Assembler::xorq(CpuRegister dst, const Address& src) { 1484 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1485 EmitRex64(dst, src); 1486 EmitUint8(0x33); 1487 EmitOperand(dst.LowBits(), src); 1488 } 1489 1490 1491 #if 0 1492 void X86_64Assembler::rex(bool force, bool w, Register* r, Register* x, Register* b) { 1493 // REX.WRXB 1494 // W - 64-bit operand 1495 // R - MODRM.reg 1496 // X - SIB.index 1497 // B - MODRM.rm/SIB.base 1498 uint8_t rex = force ? 0x40 : 0; 1499 if (w) { 1500 rex |= 0x48; // REX.W000 1501 } 1502 if (r != nullptr && *r >= Register::R8 && *r < Register::kNumberOfCpuRegisters) { 1503 rex |= 0x44; // REX.0R00 1504 *r = static_cast<Register>(*r - 8); 1505 } 1506 if (x != nullptr && *x >= Register::R8 && *x < Register::kNumberOfCpuRegisters) { 1507 rex |= 0x42; // REX.00X0 1508 *x = static_cast<Register>(*x - 8); 1509 } 1510 if (b != nullptr && *b >= Register::R8 && *b < Register::kNumberOfCpuRegisters) { 1511 rex |= 0x41; // REX.000B 1512 *b = static_cast<Register>(*b - 8); 1513 } 1514 if (rex != 0) { 1515 EmitUint8(rex); 1516 } 1517 } 1518 1519 void X86_64Assembler::rex_reg_mem(bool force, bool w, Register* dst, const Address& mem) { 1520 // REX.WRXB 1521 // W - 64-bit operand 1522 // R - MODRM.reg 1523 // X - SIB.index 1524 // B - MODRM.rm/SIB.base 1525 uint8_t rex = mem->rex(); 1526 if (force) { 1527 rex |= 0x40; // REX.0000 1528 } 1529 if (w) { 1530 rex |= 0x48; // REX.W000 1531 } 1532 if (dst != nullptr && *dst >= Register::R8 && *dst < Register::kNumberOfCpuRegisters) { 1533 rex |= 0x44; // REX.0R00 1534 *dst = static_cast<Register>(*dst - 8); 1535 } 1536 if (rex != 0) { 1537 EmitUint8(rex); 1538 } 1539 } 1540 1541 void rex_mem_reg(bool force, bool w, Address* mem, Register* src); 1542 #endif 1543 1544 void X86_64Assembler::addl(CpuRegister reg, const Immediate& imm) { 1545 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1546 EmitOptionalRex32(reg); 1547 EmitComplex(0, Operand(reg), imm); 1548 } 1549 1550 1551 void X86_64Assembler::addq(CpuRegister reg, const Immediate& imm) { 1552 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1553 CHECK(imm.is_int32()); // addq only supports 32b immediate. 1554 EmitRex64(reg); 1555 EmitComplex(0, Operand(reg), imm); 1556 } 1557 1558 1559 void X86_64Assembler::addq(CpuRegister dst, const Address& address) { 1560 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1561 EmitRex64(dst, address); 1562 EmitUint8(0x03); 1563 EmitOperand(dst.LowBits(), address); 1564 } 1565 1566 1567 void X86_64Assembler::addq(CpuRegister dst, CpuRegister src) { 1568 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1569 // 0x01 is addq r/m64 <- r/m64 + r64, with op1 in r/m and op2 in reg: so reverse EmitRex64 1570 EmitRex64(src, dst); 1571 EmitUint8(0x01); 1572 EmitRegisterOperand(src.LowBits(), dst.LowBits()); 1573 } 1574 1575 1576 void X86_64Assembler::addl(const Address& address, CpuRegister reg) { 1577 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1578 EmitOptionalRex32(reg, address); 1579 EmitUint8(0x01); 1580 EmitOperand(reg.LowBits(), address); 1581 } 1582 1583 1584 void X86_64Assembler::addl(const Address& address, const Immediate& imm) { 1585 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1586 EmitOptionalRex32(address); 1587 EmitComplex(0, address, imm); 1588 } 1589 1590 1591 void X86_64Assembler::subl(CpuRegister dst, CpuRegister src) { 1592 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1593 EmitOptionalRex32(dst, src); 1594 EmitUint8(0x2B); 1595 EmitOperand(dst.LowBits(), Operand(src)); 1596 } 1597 1598 1599 void X86_64Assembler::subl(CpuRegister reg, const Immediate& imm) { 1600 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1601 EmitOptionalRex32(reg); 1602 EmitComplex(5, Operand(reg), imm); 1603 } 1604 1605 1606 void X86_64Assembler::subq(CpuRegister reg, const Immediate& imm) { 1607 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1608 CHECK(imm.is_int32()); // subq only supports 32b immediate. 1609 EmitRex64(reg); 1610 EmitComplex(5, Operand(reg), imm); 1611 } 1612 1613 1614 void X86_64Assembler::subq(CpuRegister dst, CpuRegister src) { 1615 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1616 EmitRex64(dst, src); 1617 EmitUint8(0x2B); 1618 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 1619 } 1620 1621 1622 void X86_64Assembler::subq(CpuRegister reg, const Address& address) { 1623 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1624 EmitRex64(reg, address); 1625 EmitUint8(0x2B); 1626 EmitOperand(reg.LowBits() & 7, address); 1627 } 1628 1629 1630 void X86_64Assembler::subl(CpuRegister reg, const Address& address) { 1631 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1632 EmitOptionalRex32(reg, address); 1633 EmitUint8(0x2B); 1634 EmitOperand(reg.LowBits(), address); 1635 } 1636 1637 1638 void X86_64Assembler::cdq() { 1639 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1640 EmitUint8(0x99); 1641 } 1642 1643 1644 void X86_64Assembler::cqo() { 1645 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1646 EmitRex64(); 1647 EmitUint8(0x99); 1648 } 1649 1650 1651 void X86_64Assembler::idivl(CpuRegister reg) { 1652 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1653 EmitOptionalRex32(reg); 1654 EmitUint8(0xF7); 1655 EmitUint8(0xF8 | reg.LowBits()); 1656 } 1657 1658 1659 void X86_64Assembler::idivq(CpuRegister reg) { 1660 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1661 EmitRex64(reg); 1662 EmitUint8(0xF7); 1663 EmitUint8(0xF8 | reg.LowBits()); 1664 } 1665 1666 1667 void X86_64Assembler::imull(CpuRegister dst, CpuRegister src) { 1668 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1669 EmitOptionalRex32(dst, src); 1670 EmitUint8(0x0F); 1671 EmitUint8(0xAF); 1672 EmitOperand(dst.LowBits(), Operand(src)); 1673 } 1674 1675 void X86_64Assembler::imull(CpuRegister reg, const Immediate& imm) { 1676 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1677 CHECK(imm.is_int32()); // imull only supports 32b immediate. 1678 1679 EmitOptionalRex32(reg, reg); 1680 1681 // See whether imm can be represented as a sign-extended 8bit value. 1682 int32_t v32 = static_cast<int32_t>(imm.value()); 1683 if (IsInt<8>(v32)) { 1684 // Sign-extension works. 1685 EmitUint8(0x6B); 1686 EmitOperand(reg.LowBits(), Operand(reg)); 1687 EmitUint8(static_cast<uint8_t>(v32 & 0xFF)); 1688 } else { 1689 // Not representable, use full immediate. 1690 EmitUint8(0x69); 1691 EmitOperand(reg.LowBits(), Operand(reg)); 1692 EmitImmediate(imm); 1693 } 1694 } 1695 1696 1697 void X86_64Assembler::imull(CpuRegister reg, const Address& address) { 1698 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1699 EmitOptionalRex32(reg, address); 1700 EmitUint8(0x0F); 1701 EmitUint8(0xAF); 1702 EmitOperand(reg.LowBits(), address); 1703 } 1704 1705 1706 void X86_64Assembler::imulq(CpuRegister dst, CpuRegister src) { 1707 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1708 EmitRex64(dst, src); 1709 EmitUint8(0x0F); 1710 EmitUint8(0xAF); 1711 EmitRegisterOperand(dst.LowBits(), src.LowBits()); 1712 } 1713 1714 1715 void X86_64Assembler::imulq(CpuRegister reg, const Immediate& imm) { 1716 imulq(reg, reg, imm); 1717 } 1718 1719 void X86_64Assembler::imulq(CpuRegister dst, CpuRegister reg, const Immediate& imm) { 1720 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1721 CHECK(imm.is_int32()); // imulq only supports 32b immediate. 1722 1723 EmitRex64(dst, reg); 1724 1725 // See whether imm can be represented as a sign-extended 8bit value. 1726 int64_t v64 = imm.value(); 1727 if (IsInt<8>(v64)) { 1728 // Sign-extension works. 1729 EmitUint8(0x6B); 1730 EmitOperand(dst.LowBits(), Operand(reg)); 1731 EmitUint8(static_cast<uint8_t>(v64 & 0xFF)); 1732 } else { 1733 // Not representable, use full immediate. 1734 EmitUint8(0x69); 1735 EmitOperand(dst.LowBits(), Operand(reg)); 1736 EmitImmediate(imm); 1737 } 1738 } 1739 1740 void X86_64Assembler::imulq(CpuRegister reg, const Address& address) { 1741 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1742 EmitRex64(reg, address); 1743 EmitUint8(0x0F); 1744 EmitUint8(0xAF); 1745 EmitOperand(reg.LowBits(), address); 1746 } 1747 1748 1749 void X86_64Assembler::imull(CpuRegister reg) { 1750 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1751 EmitOptionalRex32(reg); 1752 EmitUint8(0xF7); 1753 EmitOperand(5, Operand(reg)); 1754 } 1755 1756 1757 void X86_64Assembler::imulq(CpuRegister reg) { 1758 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1759 EmitRex64(reg); 1760 EmitUint8(0xF7); 1761 EmitOperand(5, Operand(reg)); 1762 } 1763 1764 1765 void X86_64Assembler::imull(const Address& address) { 1766 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1767 EmitOptionalRex32(address); 1768 EmitUint8(0xF7); 1769 EmitOperand(5, address); 1770 } 1771 1772 1773 void X86_64Assembler::mull(CpuRegister reg) { 1774 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1775 EmitOptionalRex32(reg); 1776 EmitUint8(0xF7); 1777 EmitOperand(4, Operand(reg)); 1778 } 1779 1780 1781 void X86_64Assembler::mull(const Address& address) { 1782 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1783 EmitOptionalRex32(address); 1784 EmitUint8(0xF7); 1785 EmitOperand(4, address); 1786 } 1787 1788 1789 void X86_64Assembler::shll(CpuRegister reg, const Immediate& imm) { 1790 EmitGenericShift(false, 4, reg, imm); 1791 } 1792 1793 1794 void X86_64Assembler::shlq(CpuRegister reg, const Immediate& imm) { 1795 EmitGenericShift(true, 4, reg, imm); 1796 } 1797 1798 1799 void X86_64Assembler::shll(CpuRegister operand, CpuRegister shifter) { 1800 EmitGenericShift(false, 4, operand, shifter); 1801 } 1802 1803 1804 void X86_64Assembler::shlq(CpuRegister operand, CpuRegister shifter) { 1805 EmitGenericShift(true, 4, operand, shifter); 1806 } 1807 1808 1809 void X86_64Assembler::shrl(CpuRegister reg, const Immediate& imm) { 1810 EmitGenericShift(false, 5, reg, imm); 1811 } 1812 1813 1814 void X86_64Assembler::shrq(CpuRegister reg, const Immediate& imm) { 1815 EmitGenericShift(true, 5, reg, imm); 1816 } 1817 1818 1819 void X86_64Assembler::shrl(CpuRegister operand, CpuRegister shifter) { 1820 EmitGenericShift(false, 5, operand, shifter); 1821 } 1822 1823 1824 void X86_64Assembler::shrq(CpuRegister operand, CpuRegister shifter) { 1825 EmitGenericShift(true, 5, operand, shifter); 1826 } 1827 1828 1829 void X86_64Assembler::sarl(CpuRegister reg, const Immediate& imm) { 1830 EmitGenericShift(false, 7, reg, imm); 1831 } 1832 1833 1834 void X86_64Assembler::sarl(CpuRegister operand, CpuRegister shifter) { 1835 EmitGenericShift(false, 7, operand, shifter); 1836 } 1837 1838 1839 void X86_64Assembler::sarq(CpuRegister reg, const Immediate& imm) { 1840 EmitGenericShift(true, 7, reg, imm); 1841 } 1842 1843 1844 void X86_64Assembler::sarq(CpuRegister operand, CpuRegister shifter) { 1845 EmitGenericShift(true, 7, operand, shifter); 1846 } 1847 1848 1849 void X86_64Assembler::negl(CpuRegister reg) { 1850 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1851 EmitOptionalRex32(reg); 1852 EmitUint8(0xF7); 1853 EmitOperand(3, Operand(reg)); 1854 } 1855 1856 1857 void X86_64Assembler::negq(CpuRegister reg) { 1858 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1859 EmitRex64(reg); 1860 EmitUint8(0xF7); 1861 EmitOperand(3, Operand(reg)); 1862 } 1863 1864 1865 void X86_64Assembler::notl(CpuRegister reg) { 1866 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1867 EmitOptionalRex32(reg); 1868 EmitUint8(0xF7); 1869 EmitUint8(0xD0 | reg.LowBits()); 1870 } 1871 1872 1873 void X86_64Assembler::notq(CpuRegister reg) { 1874 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1875 EmitRex64(reg); 1876 EmitUint8(0xF7); 1877 EmitOperand(2, Operand(reg)); 1878 } 1879 1880 1881 void X86_64Assembler::enter(const Immediate& imm) { 1882 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1883 EmitUint8(0xC8); 1884 CHECK(imm.is_uint16()) << imm.value(); 1885 EmitUint8(imm.value() & 0xFF); 1886 EmitUint8((imm.value() >> 8) & 0xFF); 1887 EmitUint8(0x00); 1888 } 1889 1890 1891 void X86_64Assembler::leave() { 1892 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1893 EmitUint8(0xC9); 1894 } 1895 1896 1897 void X86_64Assembler::ret() { 1898 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1899 EmitUint8(0xC3); 1900 } 1901 1902 1903 void X86_64Assembler::ret(const Immediate& imm) { 1904 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1905 EmitUint8(0xC2); 1906 CHECK(imm.is_uint16()); 1907 EmitUint8(imm.value() & 0xFF); 1908 EmitUint8((imm.value() >> 8) & 0xFF); 1909 } 1910 1911 1912 1913 void X86_64Assembler::nop() { 1914 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1915 EmitUint8(0x90); 1916 } 1917 1918 1919 void X86_64Assembler::int3() { 1920 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1921 EmitUint8(0xCC); 1922 } 1923 1924 1925 void X86_64Assembler::hlt() { 1926 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1927 EmitUint8(0xF4); 1928 } 1929 1930 1931 void X86_64Assembler::j(Condition condition, Label* label) { 1932 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1933 if (label->IsBound()) { 1934 static const int kShortSize = 2; 1935 static const int kLongSize = 6; 1936 int offset = label->Position() - buffer_.Size(); 1937 CHECK_LE(offset, 0); 1938 if (IsInt<8>(offset - kShortSize)) { 1939 EmitUint8(0x70 + condition); 1940 EmitUint8((offset - kShortSize) & 0xFF); 1941 } else { 1942 EmitUint8(0x0F); 1943 EmitUint8(0x80 + condition); 1944 EmitInt32(offset - kLongSize); 1945 } 1946 } else { 1947 EmitUint8(0x0F); 1948 EmitUint8(0x80 + condition); 1949 EmitLabelLink(label); 1950 } 1951 } 1952 1953 1954 void X86_64Assembler::jmp(CpuRegister reg) { 1955 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1956 EmitOptionalRex32(reg); 1957 EmitUint8(0xFF); 1958 EmitRegisterOperand(4, reg.LowBits()); 1959 } 1960 1961 void X86_64Assembler::jmp(const Address& address) { 1962 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1963 EmitOptionalRex32(address); 1964 EmitUint8(0xFF); 1965 EmitOperand(4, address); 1966 } 1967 1968 void X86_64Assembler::jmp(Label* label) { 1969 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1970 if (label->IsBound()) { 1971 static const int kShortSize = 2; 1972 static const int kLongSize = 5; 1973 int offset = label->Position() - buffer_.Size(); 1974 CHECK_LE(offset, 0); 1975 if (IsInt<8>(offset - kShortSize)) { 1976 EmitUint8(0xEB); 1977 EmitUint8((offset - kShortSize) & 0xFF); 1978 } else { 1979 EmitUint8(0xE9); 1980 EmitInt32(offset - kLongSize); 1981 } 1982 } else { 1983 EmitUint8(0xE9); 1984 EmitLabelLink(label); 1985 } 1986 } 1987 1988 1989 X86_64Assembler* X86_64Assembler::lock() { 1990 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1991 EmitUint8(0xF0); 1992 return this; 1993 } 1994 1995 1996 void X86_64Assembler::cmpxchgl(const Address& address, CpuRegister reg) { 1997 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1998 EmitOptionalRex32(reg, address); 1999 EmitUint8(0x0F); 2000 EmitUint8(0xB1); 2001 EmitOperand(reg.LowBits(), address); 2002 } 2003 2004 2005 void X86_64Assembler::cmpxchgq(const Address& address, CpuRegister reg) { 2006 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2007 EmitRex64(reg, address); 2008 EmitUint8(0x0F); 2009 EmitUint8(0xB1); 2010 EmitOperand(reg.LowBits(), address); 2011 } 2012 2013 2014 void X86_64Assembler::mfence() { 2015 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2016 EmitUint8(0x0F); 2017 EmitUint8(0xAE); 2018 EmitUint8(0xF0); 2019 } 2020 2021 2022 X86_64Assembler* X86_64Assembler::gs() { 2023 // TODO: gs is a prefix and not an instruction 2024 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2025 EmitUint8(0x65); 2026 return this; 2027 } 2028 2029 2030 void X86_64Assembler::AddImmediate(CpuRegister reg, const Immediate& imm) { 2031 int value = imm.value(); 2032 if (value != 0) { 2033 if (value > 0) { 2034 addl(reg, imm); 2035 } else { 2036 subl(reg, Immediate(value)); 2037 } 2038 } 2039 } 2040 2041 2042 void X86_64Assembler::setcc(Condition condition, CpuRegister dst) { 2043 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2044 // RSP, RBP, RDI, RSI need rex prefix (else the pattern encodes ah/bh/ch/dh). 2045 if (dst.NeedsRex() || dst.AsRegister() > 3) { 2046 EmitOptionalRex(true, false, false, false, dst.NeedsRex()); 2047 } 2048 EmitUint8(0x0F); 2049 EmitUint8(0x90 + condition); 2050 EmitUint8(0xC0 + dst.LowBits()); 2051 } 2052 2053 void X86_64Assembler::bswapl(CpuRegister dst) { 2054 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2055 EmitOptionalRex(false, false, false, false, dst.NeedsRex()); 2056 EmitUint8(0x0F); 2057 EmitUint8(0xC8 + dst.LowBits()); 2058 } 2059 2060 void X86_64Assembler::bswapq(CpuRegister dst) { 2061 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2062 EmitOptionalRex(false, true, false, false, dst.NeedsRex()); 2063 EmitUint8(0x0F); 2064 EmitUint8(0xC8 + dst.LowBits()); 2065 } 2066 2067 2068 void X86_64Assembler::repne_scasw() { 2069 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2070 EmitUint8(0x66); 2071 EmitUint8(0xF2); 2072 EmitUint8(0xAF); 2073 } 2074 2075 2076 void X86_64Assembler::LoadDoubleConstant(XmmRegister dst, double value) { 2077 // TODO: Need to have a code constants table. 2078 int64_t constant = bit_cast<int64_t, double>(value); 2079 pushq(Immediate(High32Bits(constant))); 2080 pushq(Immediate(Low32Bits(constant))); 2081 movsd(dst, Address(CpuRegister(RSP), 0)); 2082 addq(CpuRegister(RSP), Immediate(2 * sizeof(intptr_t))); 2083 } 2084 2085 2086 void X86_64Assembler::Align(int alignment, int offset) { 2087 CHECK(IsPowerOfTwo(alignment)); 2088 // Emit nop instruction until the real position is aligned. 2089 while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) { 2090 nop(); 2091 } 2092 } 2093 2094 2095 void X86_64Assembler::Bind(Label* label) { 2096 int bound = buffer_.Size(); 2097 CHECK(!label->IsBound()); // Labels can only be bound once. 2098 while (label->IsLinked()) { 2099 int position = label->LinkPosition(); 2100 int next = buffer_.Load<int32_t>(position); 2101 buffer_.Store<int32_t>(position, bound - (position + 4)); 2102 label->position_ = next; 2103 } 2104 label->BindTo(bound); 2105 } 2106 2107 2108 void X86_64Assembler::EmitOperand(uint8_t reg_or_opcode, const Operand& operand) { 2109 CHECK_GE(reg_or_opcode, 0); 2110 CHECK_LT(reg_or_opcode, 8); 2111 const int length = operand.length_; 2112 CHECK_GT(length, 0); 2113 // Emit the ModRM byte updated with the given reg value. 2114 CHECK_EQ(operand.encoding_[0] & 0x38, 0); 2115 EmitUint8(operand.encoding_[0] + (reg_or_opcode << 3)); 2116 // Emit the rest of the encoded operand. 2117 for (int i = 1; i < length; i++) { 2118 EmitUint8(operand.encoding_[i]); 2119 } 2120 AssemblerFixup* fixup = operand.GetFixup(); 2121 if (fixup != nullptr) { 2122 EmitFixup(fixup); 2123 } 2124 } 2125 2126 2127 void X86_64Assembler::EmitImmediate(const Immediate& imm) { 2128 if (imm.is_int32()) { 2129 EmitInt32(static_cast<int32_t>(imm.value())); 2130 } else { 2131 EmitInt64(imm.value()); 2132 } 2133 } 2134 2135 2136 void X86_64Assembler::EmitComplex(uint8_t reg_or_opcode, 2137 const Operand& operand, 2138 const Immediate& immediate) { 2139 CHECK_GE(reg_or_opcode, 0); 2140 CHECK_LT(reg_or_opcode, 8); 2141 if (immediate.is_int8()) { 2142 // Use sign-extended 8-bit immediate. 2143 EmitUint8(0x83); 2144 EmitOperand(reg_or_opcode, operand); 2145 EmitUint8(immediate.value() & 0xFF); 2146 } else if (operand.IsRegister(CpuRegister(RAX))) { 2147 // Use short form if the destination is eax. 2148 EmitUint8(0x05 + (reg_or_opcode << 3)); 2149 EmitImmediate(immediate); 2150 } else { 2151 EmitUint8(0x81); 2152 EmitOperand(reg_or_opcode, operand); 2153 EmitImmediate(immediate); 2154 } 2155 } 2156 2157 2158 void X86_64Assembler::EmitLabel(Label* label, int instruction_size) { 2159 if (label->IsBound()) { 2160 int offset = label->Position() - buffer_.Size(); 2161 CHECK_LE(offset, 0); 2162 EmitInt32(offset - instruction_size); 2163 } else { 2164 EmitLabelLink(label); 2165 } 2166 } 2167 2168 2169 void X86_64Assembler::EmitLabelLink(Label* label) { 2170 CHECK(!label->IsBound()); 2171 int position = buffer_.Size(); 2172 EmitInt32(label->position_); 2173 label->LinkTo(position); 2174 } 2175 2176 2177 void X86_64Assembler::EmitGenericShift(bool wide, 2178 int reg_or_opcode, 2179 CpuRegister reg, 2180 const Immediate& imm) { 2181 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2182 CHECK(imm.is_int8()); 2183 if (wide) { 2184 EmitRex64(reg); 2185 } else { 2186 EmitOptionalRex32(reg); 2187 } 2188 if (imm.value() == 1) { 2189 EmitUint8(0xD1); 2190 EmitOperand(reg_or_opcode, Operand(reg)); 2191 } else { 2192 EmitUint8(0xC1); 2193 EmitOperand(reg_or_opcode, Operand(reg)); 2194 EmitUint8(imm.value() & 0xFF); 2195 } 2196 } 2197 2198 2199 void X86_64Assembler::EmitGenericShift(bool wide, 2200 int reg_or_opcode, 2201 CpuRegister operand, 2202 CpuRegister shifter) { 2203 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2204 CHECK_EQ(shifter.AsRegister(), RCX); 2205 if (wide) { 2206 EmitRex64(operand); 2207 } else { 2208 EmitOptionalRex32(operand); 2209 } 2210 EmitUint8(0xD3); 2211 EmitOperand(reg_or_opcode, Operand(operand)); 2212 } 2213 2214 void X86_64Assembler::EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) { 2215 // REX.WRXB 2216 // W - 64-bit operand 2217 // R - MODRM.reg 2218 // X - SIB.index 2219 // B - MODRM.rm/SIB.base 2220 uint8_t rex = force ? 0x40 : 0; 2221 if (w) { 2222 rex |= 0x48; // REX.W000 2223 } 2224 if (r) { 2225 rex |= 0x44; // REX.0R00 2226 } 2227 if (x) { 2228 rex |= 0x42; // REX.00X0 2229 } 2230 if (b) { 2231 rex |= 0x41; // REX.000B 2232 } 2233 if (rex != 0) { 2234 EmitUint8(rex); 2235 } 2236 } 2237 2238 void X86_64Assembler::EmitOptionalRex32(CpuRegister reg) { 2239 EmitOptionalRex(false, false, false, false, reg.NeedsRex()); 2240 } 2241 2242 void X86_64Assembler::EmitOptionalRex32(CpuRegister dst, CpuRegister src) { 2243 EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex()); 2244 } 2245 2246 void X86_64Assembler::EmitOptionalRex32(XmmRegister dst, XmmRegister src) { 2247 EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex()); 2248 } 2249 2250 void X86_64Assembler::EmitOptionalRex32(CpuRegister dst, XmmRegister src) { 2251 EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex()); 2252 } 2253 2254 void X86_64Assembler::EmitOptionalRex32(XmmRegister dst, CpuRegister src) { 2255 EmitOptionalRex(false, false, dst.NeedsRex(), false, src.NeedsRex()); 2256 } 2257 2258 void X86_64Assembler::EmitOptionalRex32(const Operand& operand) { 2259 uint8_t rex = operand.rex(); 2260 if (rex != 0) { 2261 EmitUint8(rex); 2262 } 2263 } 2264 2265 void X86_64Assembler::EmitOptionalRex32(CpuRegister dst, const Operand& operand) { 2266 uint8_t rex = operand.rex(); 2267 if (dst.NeedsRex()) { 2268 rex |= 0x44; // REX.0R00 2269 } 2270 if (rex != 0) { 2271 EmitUint8(rex); 2272 } 2273 } 2274 2275 void X86_64Assembler::EmitOptionalRex32(XmmRegister dst, const Operand& operand) { 2276 uint8_t rex = operand.rex(); 2277 if (dst.NeedsRex()) { 2278 rex |= 0x44; // REX.0R00 2279 } 2280 if (rex != 0) { 2281 EmitUint8(rex); 2282 } 2283 } 2284 2285 void X86_64Assembler::EmitRex64() { 2286 EmitOptionalRex(false, true, false, false, false); 2287 } 2288 2289 void X86_64Assembler::EmitRex64(CpuRegister reg) { 2290 EmitOptionalRex(false, true, false, false, reg.NeedsRex()); 2291 } 2292 2293 void X86_64Assembler::EmitRex64(const Operand& operand) { 2294 uint8_t rex = operand.rex(); 2295 rex |= 0x48; // REX.W000 2296 EmitUint8(rex); 2297 } 2298 2299 void X86_64Assembler::EmitRex64(CpuRegister dst, CpuRegister src) { 2300 EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex()); 2301 } 2302 2303 void X86_64Assembler::EmitRex64(XmmRegister dst, CpuRegister src) { 2304 EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex()); 2305 } 2306 2307 void X86_64Assembler::EmitRex64(CpuRegister dst, XmmRegister src) { 2308 EmitOptionalRex(false, true, dst.NeedsRex(), false, src.NeedsRex()); 2309 } 2310 2311 void X86_64Assembler::EmitRex64(CpuRegister dst, const Operand& operand) { 2312 uint8_t rex = 0x48 | operand.rex(); // REX.W000 2313 if (dst.NeedsRex()) { 2314 rex |= 0x44; // REX.0R00 2315 } 2316 EmitUint8(rex); 2317 } 2318 2319 void X86_64Assembler::EmitRex64(XmmRegister dst, const Operand& operand) { 2320 uint8_t rex = 0x48 | operand.rex(); // REX.W000 2321 if (dst.NeedsRex()) { 2322 rex |= 0x44; // REX.0R00 2323 } 2324 EmitUint8(rex); 2325 } 2326 2327 void X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, CpuRegister src) { 2328 // For src, SPL, BPL, SIL, DIL need the rex prefix. 2329 bool force = src.AsRegister() > 3; 2330 EmitOptionalRex(force, false, dst.NeedsRex(), false, src.NeedsRex()); 2331 } 2332 2333 void X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, const Operand& operand) { 2334 uint8_t rex = operand.rex(); 2335 // For dst, SPL, BPL, SIL, DIL need the rex prefix. 2336 bool force = dst.AsRegister() > 3; 2337 if (force) { 2338 rex |= 0x40; // REX.0000 2339 } 2340 if (dst.NeedsRex()) { 2341 rex |= 0x44; // REX.0R00 2342 } 2343 if (rex != 0) { 2344 EmitUint8(rex); 2345 } 2346 } 2347 2348 static dwarf::Reg DWARFReg(Register reg) { 2349 return dwarf::Reg::X86_64Core(static_cast<int>(reg)); 2350 } 2351 static dwarf::Reg DWARFReg(FloatRegister reg) { 2352 return dwarf::Reg::X86_64Fp(static_cast<int>(reg)); 2353 } 2354 2355 constexpr size_t kFramePointerSize = 8; 2356 2357 void X86_64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, 2358 const std::vector<ManagedRegister>& spill_regs, 2359 const ManagedRegisterEntrySpills& entry_spills) { 2360 DCHECK_EQ(buffer_.Size(), 0U); // Nothing emitted yet. 2361 cfi_.SetCurrentCFAOffset(8); // Return address on stack. 2362 CHECK_ALIGNED(frame_size, kStackAlignment); 2363 int gpr_count = 0; 2364 for (int i = spill_regs.size() - 1; i >= 0; --i) { 2365 x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64(); 2366 if (spill.IsCpuRegister()) { 2367 pushq(spill.AsCpuRegister()); 2368 gpr_count++; 2369 cfi_.AdjustCFAOffset(kFramePointerSize); 2370 cfi_.RelOffset(DWARFReg(spill.AsCpuRegister().AsRegister()), 0); 2371 } 2372 } 2373 // return address then method on stack. 2374 int64_t rest_of_frame = static_cast<int64_t>(frame_size) 2375 - (gpr_count * kFramePointerSize) 2376 - kFramePointerSize /*return address*/; 2377 subq(CpuRegister(RSP), Immediate(rest_of_frame)); 2378 cfi_.AdjustCFAOffset(rest_of_frame); 2379 2380 // spill xmms 2381 int64_t offset = rest_of_frame; 2382 for (int i = spill_regs.size() - 1; i >= 0; --i) { 2383 x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64(); 2384 if (spill.IsXmmRegister()) { 2385 offset -= sizeof(double); 2386 movsd(Address(CpuRegister(RSP), offset), spill.AsXmmRegister()); 2387 cfi_.RelOffset(DWARFReg(spill.AsXmmRegister().AsFloatRegister()), offset); 2388 } 2389 } 2390 2391 DCHECK_EQ(kX86_64PointerSize, kFramePointerSize); 2392 2393 movq(Address(CpuRegister(RSP), 0), method_reg.AsX86_64().AsCpuRegister()); 2394 2395 for (size_t i = 0; i < entry_spills.size(); ++i) { 2396 ManagedRegisterSpill spill = entry_spills.at(i); 2397 if (spill.AsX86_64().IsCpuRegister()) { 2398 if (spill.getSize() == 8) { 2399 movq(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), 2400 spill.AsX86_64().AsCpuRegister()); 2401 } else { 2402 CHECK_EQ(spill.getSize(), 4); 2403 movl(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsCpuRegister()); 2404 } 2405 } else { 2406 if (spill.getSize() == 8) { 2407 movsd(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister()); 2408 } else { 2409 CHECK_EQ(spill.getSize(), 4); 2410 movss(Address(CpuRegister(RSP), frame_size + spill.getSpillOffset()), spill.AsX86_64().AsXmmRegister()); 2411 } 2412 } 2413 } 2414 } 2415 2416 void X86_64Assembler::RemoveFrame(size_t frame_size, 2417 const std::vector<ManagedRegister>& spill_regs) { 2418 CHECK_ALIGNED(frame_size, kStackAlignment); 2419 cfi_.RememberState(); 2420 int gpr_count = 0; 2421 // unspill xmms 2422 int64_t offset = static_cast<int64_t>(frame_size) - (spill_regs.size() * kFramePointerSize) - 2 * kFramePointerSize; 2423 for (size_t i = 0; i < spill_regs.size(); ++i) { 2424 x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64(); 2425 if (spill.IsXmmRegister()) { 2426 offset += sizeof(double); 2427 movsd(spill.AsXmmRegister(), Address(CpuRegister(RSP), offset)); 2428 cfi_.Restore(DWARFReg(spill.AsXmmRegister().AsFloatRegister())); 2429 } else { 2430 gpr_count++; 2431 } 2432 } 2433 int adjust = static_cast<int>(frame_size) - (gpr_count * kFramePointerSize) - kFramePointerSize; 2434 addq(CpuRegister(RSP), Immediate(adjust)); 2435 cfi_.AdjustCFAOffset(-adjust); 2436 for (size_t i = 0; i < spill_regs.size(); ++i) { 2437 x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64(); 2438 if (spill.IsCpuRegister()) { 2439 popq(spill.AsCpuRegister()); 2440 cfi_.AdjustCFAOffset(-static_cast<int>(kFramePointerSize)); 2441 cfi_.Restore(DWARFReg(spill.AsCpuRegister().AsRegister())); 2442 } 2443 } 2444 ret(); 2445 // The CFI should be restored for any code that follows the exit block. 2446 cfi_.RestoreState(); 2447 cfi_.DefCFAOffset(frame_size); 2448 } 2449 2450 void X86_64Assembler::IncreaseFrameSize(size_t adjust) { 2451 CHECK_ALIGNED(adjust, kStackAlignment); 2452 addq(CpuRegister(RSP), Immediate(-static_cast<int64_t>(adjust))); 2453 cfi_.AdjustCFAOffset(adjust); 2454 } 2455 2456 void X86_64Assembler::DecreaseFrameSize(size_t adjust) { 2457 CHECK_ALIGNED(adjust, kStackAlignment); 2458 addq(CpuRegister(RSP), Immediate(adjust)); 2459 cfi_.AdjustCFAOffset(-adjust); 2460 } 2461 2462 void X86_64Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) { 2463 X86_64ManagedRegister src = msrc.AsX86_64(); 2464 if (src.IsNoRegister()) { 2465 CHECK_EQ(0u, size); 2466 } else if (src.IsCpuRegister()) { 2467 if (size == 4) { 2468 CHECK_EQ(4u, size); 2469 movl(Address(CpuRegister(RSP), offs), src.AsCpuRegister()); 2470 } else { 2471 CHECK_EQ(8u, size); 2472 movq(Address(CpuRegister(RSP), offs), src.AsCpuRegister()); 2473 } 2474 } else if (src.IsRegisterPair()) { 2475 CHECK_EQ(0u, size); 2476 movq(Address(CpuRegister(RSP), offs), src.AsRegisterPairLow()); 2477 movq(Address(CpuRegister(RSP), FrameOffset(offs.Int32Value()+4)), 2478 src.AsRegisterPairHigh()); 2479 } else if (src.IsX87Register()) { 2480 if (size == 4) { 2481 fstps(Address(CpuRegister(RSP), offs)); 2482 } else { 2483 fstpl(Address(CpuRegister(RSP), offs)); 2484 } 2485 } else { 2486 CHECK(src.IsXmmRegister()); 2487 if (size == 4) { 2488 movss(Address(CpuRegister(RSP), offs), src.AsXmmRegister()); 2489 } else { 2490 movsd(Address(CpuRegister(RSP), offs), src.AsXmmRegister()); 2491 } 2492 } 2493 } 2494 2495 void X86_64Assembler::StoreRef(FrameOffset dest, ManagedRegister msrc) { 2496 X86_64ManagedRegister src = msrc.AsX86_64(); 2497 CHECK(src.IsCpuRegister()); 2498 movl(Address(CpuRegister(RSP), dest), src.AsCpuRegister()); 2499 } 2500 2501 void X86_64Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) { 2502 X86_64ManagedRegister src = msrc.AsX86_64(); 2503 CHECK(src.IsCpuRegister()); 2504 movq(Address(CpuRegister(RSP), dest), src.AsCpuRegister()); 2505 } 2506 2507 void X86_64Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm, 2508 ManagedRegister) { 2509 movl(Address(CpuRegister(RSP), dest), Immediate(imm)); // TODO(64) movq? 2510 } 2511 2512 void X86_64Assembler::StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm, 2513 ManagedRegister) { 2514 gs()->movl(Address::Absolute(dest, true), Immediate(imm)); // TODO(64) movq? 2515 } 2516 2517 void X86_64Assembler::StoreStackOffsetToThread64(ThreadOffset<8> thr_offs, 2518 FrameOffset fr_offs, 2519 ManagedRegister mscratch) { 2520 X86_64ManagedRegister scratch = mscratch.AsX86_64(); 2521 CHECK(scratch.IsCpuRegister()); 2522 leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), fr_offs)); 2523 gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister()); 2524 } 2525 2526 void X86_64Assembler::StoreStackPointerToThread64(ThreadOffset<8> thr_offs) { 2527 gs()->movq(Address::Absolute(thr_offs, true), CpuRegister(RSP)); 2528 } 2529 2530 void X86_64Assembler::StoreSpanning(FrameOffset /*dst*/, ManagedRegister /*src*/, 2531 FrameOffset /*in_off*/, ManagedRegister /*scratch*/) { 2532 UNIMPLEMENTED(FATAL); // this case only currently exists for ARM 2533 } 2534 2535 void X86_64Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) { 2536 X86_64ManagedRegister dest = mdest.AsX86_64(); 2537 if (dest.IsNoRegister()) { 2538 CHECK_EQ(0u, size); 2539 } else if (dest.IsCpuRegister()) { 2540 if (size == 4) { 2541 CHECK_EQ(4u, size); 2542 movl(dest.AsCpuRegister(), Address(CpuRegister(RSP), src)); 2543 } else { 2544 CHECK_EQ(8u, size); 2545 movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src)); 2546 } 2547 } else if (dest.IsRegisterPair()) { 2548 CHECK_EQ(0u, size); 2549 movq(dest.AsRegisterPairLow(), Address(CpuRegister(RSP), src)); 2550 movq(dest.AsRegisterPairHigh(), Address(CpuRegister(RSP), FrameOffset(src.Int32Value()+4))); 2551 } else if (dest.IsX87Register()) { 2552 if (size == 4) { 2553 flds(Address(CpuRegister(RSP), src)); 2554 } else { 2555 fldl(Address(CpuRegister(RSP), src)); 2556 } 2557 } else { 2558 CHECK(dest.IsXmmRegister()); 2559 if (size == 4) { 2560 movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), src)); 2561 } else { 2562 movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), src)); 2563 } 2564 } 2565 } 2566 2567 void X86_64Assembler::LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) { 2568 X86_64ManagedRegister dest = mdest.AsX86_64(); 2569 if (dest.IsNoRegister()) { 2570 CHECK_EQ(0u, size); 2571 } else if (dest.IsCpuRegister()) { 2572 CHECK_EQ(4u, size); 2573 gs()->movl(dest.AsCpuRegister(), Address::Absolute(src, true)); 2574 } else if (dest.IsRegisterPair()) { 2575 CHECK_EQ(8u, size); 2576 gs()->movq(dest.AsRegisterPairLow(), Address::Absolute(src, true)); 2577 } else if (dest.IsX87Register()) { 2578 if (size == 4) { 2579 gs()->flds(Address::Absolute(src, true)); 2580 } else { 2581 gs()->fldl(Address::Absolute(src, true)); 2582 } 2583 } else { 2584 CHECK(dest.IsXmmRegister()); 2585 if (size == 4) { 2586 gs()->movss(dest.AsXmmRegister(), Address::Absolute(src, true)); 2587 } else { 2588 gs()->movsd(dest.AsXmmRegister(), Address::Absolute(src, true)); 2589 } 2590 } 2591 } 2592 2593 void X86_64Assembler::LoadRef(ManagedRegister mdest, FrameOffset src) { 2594 X86_64ManagedRegister dest = mdest.AsX86_64(); 2595 CHECK(dest.IsCpuRegister()); 2596 movq(dest.AsCpuRegister(), Address(CpuRegister(RSP), src)); 2597 } 2598 2599 void X86_64Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs, 2600 bool poison_reference) { 2601 X86_64ManagedRegister dest = mdest.AsX86_64(); 2602 CHECK(dest.IsCpuRegister() && dest.IsCpuRegister()); 2603 movl(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs)); 2604 if (kPoisonHeapReferences && poison_reference) { 2605 negl(dest.AsCpuRegister()); 2606 } 2607 } 2608 2609 void X86_64Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base, 2610 Offset offs) { 2611 X86_64ManagedRegister dest = mdest.AsX86_64(); 2612 CHECK(dest.IsCpuRegister() && dest.IsCpuRegister()); 2613 movq(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs)); 2614 } 2615 2616 void X86_64Assembler::LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) { 2617 X86_64ManagedRegister dest = mdest.AsX86_64(); 2618 CHECK(dest.IsCpuRegister()); 2619 gs()->movq(dest.AsCpuRegister(), Address::Absolute(offs, true)); 2620 } 2621 2622 void X86_64Assembler::SignExtend(ManagedRegister mreg, size_t size) { 2623 X86_64ManagedRegister reg = mreg.AsX86_64(); 2624 CHECK(size == 1 || size == 2) << size; 2625 CHECK(reg.IsCpuRegister()) << reg; 2626 if (size == 1) { 2627 movsxb(reg.AsCpuRegister(), reg.AsCpuRegister()); 2628 } else { 2629 movsxw(reg.AsCpuRegister(), reg.AsCpuRegister()); 2630 } 2631 } 2632 2633 void X86_64Assembler::ZeroExtend(ManagedRegister mreg, size_t size) { 2634 X86_64ManagedRegister reg = mreg.AsX86_64(); 2635 CHECK(size == 1 || size == 2) << size; 2636 CHECK(reg.IsCpuRegister()) << reg; 2637 if (size == 1) { 2638 movzxb(reg.AsCpuRegister(), reg.AsCpuRegister()); 2639 } else { 2640 movzxw(reg.AsCpuRegister(), reg.AsCpuRegister()); 2641 } 2642 } 2643 2644 void X86_64Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) { 2645 X86_64ManagedRegister dest = mdest.AsX86_64(); 2646 X86_64ManagedRegister src = msrc.AsX86_64(); 2647 if (!dest.Equals(src)) { 2648 if (dest.IsCpuRegister() && src.IsCpuRegister()) { 2649 movq(dest.AsCpuRegister(), src.AsCpuRegister()); 2650 } else if (src.IsX87Register() && dest.IsXmmRegister()) { 2651 // Pass via stack and pop X87 register 2652 subl(CpuRegister(RSP), Immediate(16)); 2653 if (size == 4) { 2654 CHECK_EQ(src.AsX87Register(), ST0); 2655 fstps(Address(CpuRegister(RSP), 0)); 2656 movss(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0)); 2657 } else { 2658 CHECK_EQ(src.AsX87Register(), ST0); 2659 fstpl(Address(CpuRegister(RSP), 0)); 2660 movsd(dest.AsXmmRegister(), Address(CpuRegister(RSP), 0)); 2661 } 2662 addq(CpuRegister(RSP), Immediate(16)); 2663 } else { 2664 // TODO: x87, SSE 2665 UNIMPLEMENTED(FATAL) << ": Move " << dest << ", " << src; 2666 } 2667 } 2668 } 2669 2670 void X86_64Assembler::CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) { 2671 X86_64ManagedRegister scratch = mscratch.AsX86_64(); 2672 CHECK(scratch.IsCpuRegister()); 2673 movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), src)); 2674 movl(Address(CpuRegister(RSP), dest), scratch.AsCpuRegister()); 2675 } 2676 2677 void X86_64Assembler::CopyRawPtrFromThread64(FrameOffset fr_offs, 2678 ThreadOffset<8> thr_offs, 2679 ManagedRegister mscratch) { 2680 X86_64ManagedRegister scratch = mscratch.AsX86_64(); 2681 CHECK(scratch.IsCpuRegister()); 2682 gs()->movq(scratch.AsCpuRegister(), Address::Absolute(thr_offs, true)); 2683 Store(fr_offs, scratch, 8); 2684 } 2685 2686 void X86_64Assembler::CopyRawPtrToThread64(ThreadOffset<8> thr_offs, 2687 FrameOffset fr_offs, 2688 ManagedRegister mscratch) { 2689 X86_64ManagedRegister scratch = mscratch.AsX86_64(); 2690 CHECK(scratch.IsCpuRegister()); 2691 Load(scratch, fr_offs, 8); 2692 gs()->movq(Address::Absolute(thr_offs, true), scratch.AsCpuRegister()); 2693 } 2694 2695 void X86_64Assembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, 2696 size_t size) { 2697 X86_64ManagedRegister scratch = mscratch.AsX86_64(); 2698 if (scratch.IsCpuRegister() && size == 8) { 2699 Load(scratch, src, 4); 2700 Store(dest, scratch, 4); 2701 Load(scratch, FrameOffset(src.Int32Value() + 4), 4); 2702 Store(FrameOffset(dest.Int32Value() + 4), scratch, 4); 2703 } else { 2704 Load(scratch, src, size); 2705 Store(dest, scratch, size); 2706 } 2707 } 2708 2709 void X86_64Assembler::Copy(FrameOffset /*dst*/, ManagedRegister /*src_base*/, Offset /*src_offset*/, 2710 ManagedRegister /*scratch*/, size_t /*size*/) { 2711 UNIMPLEMENTED(FATAL); 2712 } 2713 2714 void X86_64Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src, 2715 ManagedRegister scratch, size_t size) { 2716 CHECK(scratch.IsNoRegister()); 2717 CHECK_EQ(size, 4u); 2718 pushq(Address(CpuRegister(RSP), src)); 2719 popq(Address(dest_base.AsX86_64().AsCpuRegister(), dest_offset)); 2720 } 2721 2722 void X86_64Assembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, 2723 ManagedRegister mscratch, size_t size) { 2724 CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister(); 2725 CHECK_EQ(size, 4u); 2726 movq(scratch, Address(CpuRegister(RSP), src_base)); 2727 movq(scratch, Address(scratch, src_offset)); 2728 movq(Address(CpuRegister(RSP), dest), scratch); 2729 } 2730 2731 void X86_64Assembler::Copy(ManagedRegister dest, Offset dest_offset, 2732 ManagedRegister src, Offset src_offset, 2733 ManagedRegister scratch, size_t size) { 2734 CHECK_EQ(size, 4u); 2735 CHECK(scratch.IsNoRegister()); 2736 pushq(Address(src.AsX86_64().AsCpuRegister(), src_offset)); 2737 popq(Address(dest.AsX86_64().AsCpuRegister(), dest_offset)); 2738 } 2739 2740 void X86_64Assembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset, 2741 ManagedRegister mscratch, size_t size) { 2742 CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister(); 2743 CHECK_EQ(size, 4u); 2744 CHECK_EQ(dest.Int32Value(), src.Int32Value()); 2745 movq(scratch, Address(CpuRegister(RSP), src)); 2746 pushq(Address(scratch, src_offset)); 2747 popq(Address(scratch, dest_offset)); 2748 } 2749 2750 void X86_64Assembler::MemoryBarrier(ManagedRegister) { 2751 mfence(); 2752 } 2753 2754 void X86_64Assembler::CreateHandleScopeEntry(ManagedRegister mout_reg, 2755 FrameOffset handle_scope_offset, 2756 ManagedRegister min_reg, bool null_allowed) { 2757 X86_64ManagedRegister out_reg = mout_reg.AsX86_64(); 2758 X86_64ManagedRegister in_reg = min_reg.AsX86_64(); 2759 if (in_reg.IsNoRegister()) { // TODO(64): && null_allowed 2760 // Use out_reg as indicator of null. 2761 in_reg = out_reg; 2762 // TODO: movzwl 2763 movl(in_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset)); 2764 } 2765 CHECK(in_reg.IsCpuRegister()); 2766 CHECK(out_reg.IsCpuRegister()); 2767 VerifyObject(in_reg, null_allowed); 2768 if (null_allowed) { 2769 Label null_arg; 2770 if (!out_reg.Equals(in_reg)) { 2771 xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister()); 2772 } 2773 testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister()); 2774 j(kZero, &null_arg); 2775 leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset)); 2776 Bind(&null_arg); 2777 } else { 2778 leaq(out_reg.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset)); 2779 } 2780 } 2781 2782 void X86_64Assembler::CreateHandleScopeEntry(FrameOffset out_off, 2783 FrameOffset handle_scope_offset, 2784 ManagedRegister mscratch, 2785 bool null_allowed) { 2786 X86_64ManagedRegister scratch = mscratch.AsX86_64(); 2787 CHECK(scratch.IsCpuRegister()); 2788 if (null_allowed) { 2789 Label null_arg; 2790 movl(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset)); 2791 testl(scratch.AsCpuRegister(), scratch.AsCpuRegister()); 2792 j(kZero, &null_arg); 2793 leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset)); 2794 Bind(&null_arg); 2795 } else { 2796 leaq(scratch.AsCpuRegister(), Address(CpuRegister(RSP), handle_scope_offset)); 2797 } 2798 Store(out_off, scratch, 8); 2799 } 2800 2801 // Given a handle scope entry, load the associated reference. 2802 void X86_64Assembler::LoadReferenceFromHandleScope(ManagedRegister mout_reg, 2803 ManagedRegister min_reg) { 2804 X86_64ManagedRegister out_reg = mout_reg.AsX86_64(); 2805 X86_64ManagedRegister in_reg = min_reg.AsX86_64(); 2806 CHECK(out_reg.IsCpuRegister()); 2807 CHECK(in_reg.IsCpuRegister()); 2808 Label null_arg; 2809 if (!out_reg.Equals(in_reg)) { 2810 xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister()); 2811 } 2812 testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister()); 2813 j(kZero, &null_arg); 2814 movq(out_reg.AsCpuRegister(), Address(in_reg.AsCpuRegister(), 0)); 2815 Bind(&null_arg); 2816 } 2817 2818 void X86_64Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) { 2819 // TODO: not validating references 2820 } 2821 2822 void X86_64Assembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) { 2823 // TODO: not validating references 2824 } 2825 2826 void X86_64Assembler::Call(ManagedRegister mbase, Offset offset, ManagedRegister) { 2827 X86_64ManagedRegister base = mbase.AsX86_64(); 2828 CHECK(base.IsCpuRegister()); 2829 call(Address(base.AsCpuRegister(), offset.Int32Value())); 2830 // TODO: place reference map on call 2831 } 2832 2833 void X86_64Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) { 2834 CpuRegister scratch = mscratch.AsX86_64().AsCpuRegister(); 2835 movq(scratch, Address(CpuRegister(RSP), base)); 2836 call(Address(scratch, offset)); 2837 } 2838 2839 void X86_64Assembler::CallFromThread64(ThreadOffset<8> offset, ManagedRegister /*mscratch*/) { 2840 gs()->call(Address::Absolute(offset, true)); 2841 } 2842 2843 void X86_64Assembler::GetCurrentThread(ManagedRegister tr) { 2844 gs()->movq(tr.AsX86_64().AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true)); 2845 } 2846 2847 void X86_64Assembler::GetCurrentThread(FrameOffset offset, ManagedRegister mscratch) { 2848 X86_64ManagedRegister scratch = mscratch.AsX86_64(); 2849 gs()->movq(scratch.AsCpuRegister(), Address::Absolute(Thread::SelfOffset<8>(), true)); 2850 movq(Address(CpuRegister(RSP), offset), scratch.AsCpuRegister()); 2851 } 2852 2853 // Slowpath entered when Thread::Current()->_exception is non-null 2854 class X86_64ExceptionSlowPath FINAL : public SlowPath { 2855 public: 2856 explicit X86_64ExceptionSlowPath(size_t stack_adjust) : stack_adjust_(stack_adjust) {} 2857 virtual void Emit(Assembler *sp_asm) OVERRIDE; 2858 private: 2859 const size_t stack_adjust_; 2860 }; 2861 2862 void X86_64Assembler::ExceptionPoll(ManagedRegister /*scratch*/, size_t stack_adjust) { 2863 X86_64ExceptionSlowPath* slow = new X86_64ExceptionSlowPath(stack_adjust); 2864 buffer_.EnqueueSlowPath(slow); 2865 gs()->cmpl(Address::Absolute(Thread::ExceptionOffset<8>(), true), Immediate(0)); 2866 j(kNotEqual, slow->Entry()); 2867 } 2868 2869 void X86_64ExceptionSlowPath::Emit(Assembler *sasm) { 2870 X86_64Assembler* sp_asm = down_cast<X86_64Assembler*>(sasm); 2871 #define __ sp_asm-> 2872 __ Bind(&entry_); 2873 // Note: the return value is dead 2874 if (stack_adjust_ != 0) { // Fix up the frame. 2875 __ DecreaseFrameSize(stack_adjust_); 2876 } 2877 // Pass exception as argument in RDI 2878 __ gs()->movq(CpuRegister(RDI), Address::Absolute(Thread::ExceptionOffset<8>(), true)); 2879 __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(8, pDeliverException), true)); 2880 // this call should never return 2881 __ int3(); 2882 #undef __ 2883 } 2884 2885 void X86_64Assembler::AddConstantArea() { 2886 const std::vector<int32_t>& area = constant_area_.GetBuffer(); 2887 for (size_t i = 0, e = area.size(); i < e; i++) { 2888 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2889 EmitInt32(area[i]); 2890 } 2891 } 2892 2893 int ConstantArea::AddInt32(int32_t v) { 2894 for (size_t i = 0, e = buffer_.size(); i < e; i++) { 2895 if (v == buffer_[i]) { 2896 return i * elem_size_; 2897 } 2898 } 2899 2900 // Didn't match anything. 2901 int result = buffer_.size() * elem_size_; 2902 buffer_.push_back(v); 2903 return result; 2904 } 2905 2906 int ConstantArea::AddInt64(int64_t v) { 2907 int32_t v_low = v; 2908 int32_t v_high = v >> 32; 2909 if (buffer_.size() > 1) { 2910 // Ensure we don't pass the end of the buffer. 2911 for (size_t i = 0, e = buffer_.size() - 1; i < e; i++) { 2912 if (v_low == buffer_[i] && v_high == buffer_[i + 1]) { 2913 return i * elem_size_; 2914 } 2915 } 2916 } 2917 2918 // Didn't match anything. 2919 int result = buffer_.size() * elem_size_; 2920 buffer_.push_back(v_low); 2921 buffer_.push_back(v_high); 2922 return result; 2923 } 2924 2925 int ConstantArea::AddDouble(double v) { 2926 // Treat the value as a 64-bit integer value. 2927 return AddInt64(bit_cast<int64_t, double>(v)); 2928 } 2929 2930 int ConstantArea::AddFloat(float v) { 2931 // Treat the value as a 32-bit integer value. 2932 return AddInt32(bit_cast<int32_t, float>(v)); 2933 } 2934 2935 } // namespace x86_64 2936 } // namespace art 2937