1 /* 2 * Copyright (C) 2011 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 #ifndef ART_COMPILER_UTILS_X86_ASSEMBLER_X86_H_ 18 #define ART_COMPILER_UTILS_X86_ASSEMBLER_X86_H_ 19 20 #include <vector> 21 22 #include "base/arena_containers.h" 23 #include "base/array_ref.h" 24 #include "base/bit_utils.h" 25 #include "base/enums.h" 26 #include "base/macros.h" 27 #include "constants_x86.h" 28 #include "globals.h" 29 #include "managed_register_x86.h" 30 #include "offsets.h" 31 #include "utils/assembler.h" 32 33 namespace art { 34 namespace x86 { 35 36 class Immediate : public ValueObject { 37 public: 38 explicit Immediate(int32_t value_in) : value_(value_in) {} 39 40 int32_t value() const { return value_; } 41 42 bool is_int8() const { return IsInt<8>(value_); } 43 bool is_uint8() const { return IsUint<8>(value_); } 44 bool is_int16() const { return IsInt<16>(value_); } 45 bool is_uint16() const { return IsUint<16>(value_); } 46 47 private: 48 const int32_t value_; 49 }; 50 51 52 class Operand : public ValueObject { 53 public: 54 uint8_t mod() const { 55 return (encoding_at(0) >> 6) & 3; 56 } 57 58 Register rm() const { 59 return static_cast<Register>(encoding_at(0) & 7); 60 } 61 62 ScaleFactor scale() const { 63 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); 64 } 65 66 Register index() const { 67 return static_cast<Register>((encoding_at(1) >> 3) & 7); 68 } 69 70 Register base() const { 71 return static_cast<Register>(encoding_at(1) & 7); 72 } 73 74 int8_t disp8() const { 75 CHECK_GE(length_, 2); 76 return static_cast<int8_t>(encoding_[length_ - 1]); 77 } 78 79 int32_t disp32() const { 80 CHECK_GE(length_, 5); 81 int32_t value; 82 memcpy(&value, &encoding_[length_ - 4], sizeof(value)); 83 return value; 84 } 85 86 bool IsRegister(Register reg) const { 87 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. 88 && ((encoding_[0] & 0x07) == reg); // Register codes match. 89 } 90 91 protected: 92 // Operand can be sub classed (e.g: Address). 93 Operand() : length_(0), fixup_(nullptr) { } 94 95 void SetModRM(int mod_in, Register rm_in) { 96 CHECK_EQ(mod_in & ~3, 0); 97 encoding_[0] = (mod_in << 6) | rm_in; 98 length_ = 1; 99 } 100 101 void SetSIB(ScaleFactor scale_in, Register index_in, Register base_in) { 102 CHECK_EQ(length_, 1); 103 CHECK_EQ(scale_in & ~3, 0); 104 encoding_[1] = (scale_in << 6) | (index_in << 3) | base_in; 105 length_ = 2; 106 } 107 108 void SetDisp8(int8_t disp) { 109 CHECK(length_ == 1 || length_ == 2); 110 encoding_[length_++] = static_cast<uint8_t>(disp); 111 } 112 113 void SetDisp32(int32_t disp) { 114 CHECK(length_ == 1 || length_ == 2); 115 int disp_size = sizeof(disp); 116 memmove(&encoding_[length_], &disp, disp_size); 117 length_ += disp_size; 118 } 119 120 AssemblerFixup* GetFixup() const { 121 return fixup_; 122 } 123 124 void SetFixup(AssemblerFixup* fixup) { 125 fixup_ = fixup; 126 } 127 128 private: 129 uint8_t length_; 130 uint8_t encoding_[6]; 131 132 // A fixup can be associated with the operand, in order to be applied after the 133 // code has been generated. This is used for constant area fixups. 134 AssemblerFixup* fixup_; 135 136 explicit Operand(Register reg) : fixup_(nullptr) { SetModRM(3, reg); } 137 138 // Get the operand encoding byte at the given index. 139 uint8_t encoding_at(int index_in) const { 140 CHECK_GE(index_in, 0); 141 CHECK_LT(index_in, length_); 142 return encoding_[index_in]; 143 } 144 145 friend class X86Assembler; 146 }; 147 148 149 class Address : public Operand { 150 public: 151 Address(Register base_in, int32_t disp) { 152 Init(base_in, disp); 153 } 154 155 Address(Register base_in, int32_t disp, AssemblerFixup *fixup) { 156 Init(base_in, disp); 157 SetFixup(fixup); 158 } 159 160 Address(Register base_in, Offset disp) { 161 Init(base_in, disp.Int32Value()); 162 } 163 164 Address(Register base_in, FrameOffset disp) { 165 CHECK_EQ(base_in, ESP); 166 Init(ESP, disp.Int32Value()); 167 } 168 169 Address(Register base_in, MemberOffset disp) { 170 Init(base_in, disp.Int32Value()); 171 } 172 173 Address(Register index_in, ScaleFactor scale_in, int32_t disp) { 174 CHECK_NE(index_in, ESP); // Illegal addressing mode. 175 SetModRM(0, ESP); 176 SetSIB(scale_in, index_in, EBP); 177 SetDisp32(disp); 178 } 179 180 Address(Register base_in, Register index_in, ScaleFactor scale_in, int32_t disp) { 181 Init(base_in, index_in, scale_in, disp); 182 } 183 184 Address(Register base_in, 185 Register index_in, 186 ScaleFactor scale_in, 187 int32_t disp, AssemblerFixup *fixup) { 188 Init(base_in, index_in, scale_in, disp); 189 SetFixup(fixup); 190 } 191 192 static Address Absolute(uintptr_t addr) { 193 Address result; 194 result.SetModRM(0, EBP); 195 result.SetDisp32(addr); 196 return result; 197 } 198 199 static Address Absolute(ThreadOffset32 addr) { 200 return Absolute(addr.Int32Value()); 201 } 202 203 private: 204 Address() {} 205 206 void Init(Register base_in, int32_t disp) { 207 if (disp == 0 && base_in != EBP) { 208 SetModRM(0, base_in); 209 if (base_in == ESP) SetSIB(TIMES_1, ESP, base_in); 210 } else if (disp >= -128 && disp <= 127) { 211 SetModRM(1, base_in); 212 if (base_in == ESP) SetSIB(TIMES_1, ESP, base_in); 213 SetDisp8(disp); 214 } else { 215 SetModRM(2, base_in); 216 if (base_in == ESP) SetSIB(TIMES_1, ESP, base_in); 217 SetDisp32(disp); 218 } 219 } 220 221 void Init(Register base_in, Register index_in, ScaleFactor scale_in, int32_t disp) { 222 CHECK_NE(index_in, ESP); // Illegal addressing mode. 223 if (disp == 0 && base_in != EBP) { 224 SetModRM(0, ESP); 225 SetSIB(scale_in, index_in, base_in); 226 } else if (disp >= -128 && disp <= 127) { 227 SetModRM(1, ESP); 228 SetSIB(scale_in, index_in, base_in); 229 SetDisp8(disp); 230 } else { 231 SetModRM(2, ESP); 232 SetSIB(scale_in, index_in, base_in); 233 SetDisp32(disp); 234 } 235 } 236 }; 237 238 239 // This is equivalent to the Label class, used in a slightly different context. We 240 // inherit the functionality of the Label class, but prevent unintended 241 // derived-to-base conversions by making the base class private. 242 class NearLabel : private Label { 243 public: 244 NearLabel() : Label() {} 245 246 // Expose the Label routines that we need. 247 using Label::Position; 248 using Label::LinkPosition; 249 using Label::IsBound; 250 using Label::IsUnused; 251 using Label::IsLinked; 252 253 private: 254 using Label::BindTo; 255 using Label::LinkTo; 256 257 friend class x86::X86Assembler; 258 259 DISALLOW_COPY_AND_ASSIGN(NearLabel); 260 }; 261 262 /** 263 * Class to handle constant area values. 264 */ 265 class ConstantArea { 266 public: 267 explicit ConstantArea(ArenaAllocator* arena) : buffer_(arena->Adapter(kArenaAllocAssembler)) {} 268 269 // Add a double to the constant area, returning the offset into 270 // the constant area where the literal resides. 271 size_t AddDouble(double v); 272 273 // Add a float to the constant area, returning the offset into 274 // the constant area where the literal resides. 275 size_t AddFloat(float v); 276 277 // Add an int32_t to the constant area, returning the offset into 278 // the constant area where the literal resides. 279 size_t AddInt32(int32_t v); 280 281 // Add an int32_t to the end of the constant area, returning the offset into 282 // the constant area where the literal resides. 283 size_t AppendInt32(int32_t v); 284 285 // Add an int64_t to the constant area, returning the offset into 286 // the constant area where the literal resides. 287 size_t AddInt64(int64_t v); 288 289 bool IsEmpty() const { 290 return buffer_.size() == 0; 291 } 292 293 size_t GetSize() const { 294 return buffer_.size() * elem_size_; 295 } 296 297 ArrayRef<const int32_t> GetBuffer() const { 298 return ArrayRef<const int32_t>(buffer_); 299 } 300 301 private: 302 static constexpr size_t elem_size_ = sizeof(int32_t); 303 ArenaVector<int32_t> buffer_; 304 }; 305 306 class X86Assembler FINAL : public Assembler { 307 public: 308 explicit X86Assembler(ArenaAllocator* arena) : Assembler(arena), constant_area_(arena) {} 309 virtual ~X86Assembler() {} 310 311 /* 312 * Emit Machine Instructions. 313 */ 314 void call(Register reg); 315 void call(const Address& address); 316 void call(Label* label); 317 void call(const ExternalLabel& label); 318 319 void pushl(Register reg); 320 void pushl(const Address& address); 321 void pushl(const Immediate& imm); 322 323 void popl(Register reg); 324 void popl(const Address& address); 325 326 void movl(Register dst, const Immediate& src); 327 void movl(Register dst, Register src); 328 329 void movl(Register dst, const Address& src); 330 void movl(const Address& dst, Register src); 331 void movl(const Address& dst, const Immediate& imm); 332 void movl(const Address& dst, Label* lbl); 333 334 void movntl(const Address& dst, Register src); 335 336 void bswapl(Register dst); 337 338 void bsfl(Register dst, Register src); 339 void bsfl(Register dst, const Address& src); 340 void bsrl(Register dst, Register src); 341 void bsrl(Register dst, const Address& src); 342 343 void popcntl(Register dst, Register src); 344 void popcntl(Register dst, const Address& src); 345 346 void rorl(Register reg, const Immediate& imm); 347 void rorl(Register operand, Register shifter); 348 void roll(Register reg, const Immediate& imm); 349 void roll(Register operand, Register shifter); 350 351 void movzxb(Register dst, ByteRegister src); 352 void movzxb(Register dst, const Address& src); 353 void movsxb(Register dst, ByteRegister src); 354 void movsxb(Register dst, const Address& src); 355 void movb(Register dst, const Address& src); 356 void movb(const Address& dst, ByteRegister src); 357 void movb(const Address& dst, const Immediate& imm); 358 359 void movzxw(Register dst, Register src); 360 void movzxw(Register dst, const Address& src); 361 void movsxw(Register dst, Register src); 362 void movsxw(Register dst, const Address& src); 363 void movw(Register dst, const Address& src); 364 void movw(const Address& dst, Register src); 365 void movw(const Address& dst, const Immediate& imm); 366 367 void leal(Register dst, const Address& src); 368 369 void cmovl(Condition condition, Register dst, Register src); 370 void cmovl(Condition condition, Register dst, const Address& src); 371 372 void setb(Condition condition, Register dst); 373 374 void movaps(XmmRegister dst, XmmRegister src); // move 375 void movaps(XmmRegister dst, const Address& src); // load aligned 376 void movups(XmmRegister dst, const Address& src); // load unaligned 377 void movaps(const Address& dst, XmmRegister src); // store aligned 378 void movups(const Address& dst, XmmRegister src); // store unaligned 379 380 void movss(XmmRegister dst, const Address& src); 381 void movss(const Address& dst, XmmRegister src); 382 void movss(XmmRegister dst, XmmRegister src); 383 384 void movd(XmmRegister dst, Register src); 385 void movd(Register dst, XmmRegister src); 386 387 void addss(XmmRegister dst, XmmRegister src); 388 void addss(XmmRegister dst, const Address& src); 389 void subss(XmmRegister dst, XmmRegister src); 390 void subss(XmmRegister dst, const Address& src); 391 void mulss(XmmRegister dst, XmmRegister src); 392 void mulss(XmmRegister dst, const Address& src); 393 void divss(XmmRegister dst, XmmRegister src); 394 void divss(XmmRegister dst, const Address& src); 395 396 void addps(XmmRegister dst, XmmRegister src); // no addr variant (for now) 397 void subps(XmmRegister dst, XmmRegister src); 398 void mulps(XmmRegister dst, XmmRegister src); 399 void divps(XmmRegister dst, XmmRegister src); 400 401 void movapd(XmmRegister dst, XmmRegister src); // move 402 void movapd(XmmRegister dst, const Address& src); // load aligned 403 void movupd(XmmRegister dst, const Address& src); // load unaligned 404 void movapd(const Address& dst, XmmRegister src); // store aligned 405 void movupd(const Address& dst, XmmRegister src); // store unaligned 406 407 void movsd(XmmRegister dst, const Address& src); 408 void movsd(const Address& dst, XmmRegister src); 409 void movsd(XmmRegister dst, XmmRegister src); 410 411 void movhpd(XmmRegister dst, const Address& src); 412 void movhpd(const Address& dst, XmmRegister src); 413 414 void addsd(XmmRegister dst, XmmRegister src); 415 void addsd(XmmRegister dst, const Address& src); 416 void subsd(XmmRegister dst, XmmRegister src); 417 void subsd(XmmRegister dst, const Address& src); 418 void mulsd(XmmRegister dst, XmmRegister src); 419 void mulsd(XmmRegister dst, const Address& src); 420 void divsd(XmmRegister dst, XmmRegister src); 421 void divsd(XmmRegister dst, const Address& src); 422 423 void addpd(XmmRegister dst, XmmRegister src); // no addr variant (for now) 424 void subpd(XmmRegister dst, XmmRegister src); 425 void mulpd(XmmRegister dst, XmmRegister src); 426 void divpd(XmmRegister dst, XmmRegister src); 427 428 void movdqa(XmmRegister dst, XmmRegister src); // move 429 void movdqa(XmmRegister dst, const Address& src); // load aligned 430 void movdqu(XmmRegister dst, const Address& src); // load unaligned 431 void movdqa(const Address& dst, XmmRegister src); // store aligned 432 void movdqu(const Address& dst, XmmRegister src); // store unaligned 433 434 void paddb(XmmRegister dst, XmmRegister src); // no addr variant (for now) 435 void psubb(XmmRegister dst, XmmRegister src); 436 437 void paddw(XmmRegister dst, XmmRegister src); 438 void psubw(XmmRegister dst, XmmRegister src); 439 void pmullw(XmmRegister dst, XmmRegister src); 440 441 void paddd(XmmRegister dst, XmmRegister src); 442 void psubd(XmmRegister dst, XmmRegister src); 443 void pmulld(XmmRegister dst, XmmRegister src); 444 445 void paddq(XmmRegister dst, XmmRegister src); 446 void psubq(XmmRegister dst, XmmRegister src); 447 448 void cvtsi2ss(XmmRegister dst, Register src); 449 void cvtsi2sd(XmmRegister dst, Register src); 450 451 void cvtss2si(Register dst, XmmRegister src); 452 void cvtss2sd(XmmRegister dst, XmmRegister src); 453 454 void cvtsd2si(Register dst, XmmRegister src); 455 void cvtsd2ss(XmmRegister dst, XmmRegister src); 456 457 void cvttss2si(Register dst, XmmRegister src); 458 void cvttsd2si(Register dst, XmmRegister src); 459 460 void cvtdq2ps(XmmRegister dst, XmmRegister src); 461 void cvtdq2pd(XmmRegister dst, XmmRegister src); 462 463 void comiss(XmmRegister a, XmmRegister b); 464 void comiss(XmmRegister a, const Address& b); 465 void comisd(XmmRegister a, XmmRegister b); 466 void comisd(XmmRegister a, const Address& b); 467 void ucomiss(XmmRegister a, XmmRegister b); 468 void ucomiss(XmmRegister a, const Address& b); 469 void ucomisd(XmmRegister a, XmmRegister b); 470 void ucomisd(XmmRegister a, const Address& b); 471 472 void roundsd(XmmRegister dst, XmmRegister src, const Immediate& imm); 473 void roundss(XmmRegister dst, XmmRegister src, const Immediate& imm); 474 475 void sqrtsd(XmmRegister dst, XmmRegister src); 476 void sqrtss(XmmRegister dst, XmmRegister src); 477 478 void xorpd(XmmRegister dst, const Address& src); 479 void xorpd(XmmRegister dst, XmmRegister src); 480 void xorps(XmmRegister dst, const Address& src); 481 void xorps(XmmRegister dst, XmmRegister src); 482 void pxor(XmmRegister dst, XmmRegister src); // no addr variant (for now) 483 484 void andpd(XmmRegister dst, XmmRegister src); 485 void andpd(XmmRegister dst, const Address& src); 486 void andps(XmmRegister dst, XmmRegister src); 487 void andps(XmmRegister dst, const Address& src); 488 void pand(XmmRegister dst, XmmRegister src); // no addr variant (for now) 489 490 void andnpd(XmmRegister dst, XmmRegister src); // no addr variant (for now) 491 void andnps(XmmRegister dst, XmmRegister src); 492 void pandn(XmmRegister dst, XmmRegister src); 493 494 void orpd(XmmRegister dst, XmmRegister src); // no addr variant (for now) 495 void orps(XmmRegister dst, XmmRegister src); 496 void por(XmmRegister dst, XmmRegister src); 497 498 void pavgb(XmmRegister dst, XmmRegister src); // no addr variant (for now) 499 void pavgw(XmmRegister dst, XmmRegister src); 500 501 void pcmpeqb(XmmRegister dst, XmmRegister src); 502 void pcmpeqw(XmmRegister dst, XmmRegister src); 503 void pcmpeqd(XmmRegister dst, XmmRegister src); 504 void pcmpeqq(XmmRegister dst, XmmRegister src); 505 506 void pcmpgtb(XmmRegister dst, XmmRegister src); 507 void pcmpgtw(XmmRegister dst, XmmRegister src); 508 void pcmpgtd(XmmRegister dst, XmmRegister src); 509 void pcmpgtq(XmmRegister dst, XmmRegister src); // SSE4.2 510 511 void shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm); 512 void shufps(XmmRegister dst, XmmRegister src, const Immediate& imm); 513 void pshufd(XmmRegister dst, XmmRegister src, const Immediate& imm); 514 515 void punpcklbw(XmmRegister dst, XmmRegister src); 516 void punpcklwd(XmmRegister dst, XmmRegister src); 517 void punpckldq(XmmRegister dst, XmmRegister src); 518 void punpcklqdq(XmmRegister dst, XmmRegister src); 519 520 void psllw(XmmRegister reg, const Immediate& shift_count); 521 void pslld(XmmRegister reg, const Immediate& shift_count); 522 void psllq(XmmRegister reg, const Immediate& shift_count); 523 524 void psraw(XmmRegister reg, const Immediate& shift_count); 525 void psrad(XmmRegister reg, const Immediate& shift_count); 526 // no psraq 527 528 void psrlw(XmmRegister reg, const Immediate& shift_count); 529 void psrld(XmmRegister reg, const Immediate& shift_count); 530 void psrlq(XmmRegister reg, const Immediate& shift_count); 531 void psrldq(XmmRegister reg, const Immediate& shift_count); 532 533 void flds(const Address& src); 534 void fstps(const Address& dst); 535 void fsts(const Address& dst); 536 537 void fldl(const Address& src); 538 void fstpl(const Address& dst); 539 void fstl(const Address& dst); 540 541 void fstsw(); 542 543 void fucompp(); 544 545 void fnstcw(const Address& dst); 546 void fldcw(const Address& src); 547 548 void fistpl(const Address& dst); 549 void fistps(const Address& dst); 550 void fildl(const Address& src); 551 void filds(const Address& src); 552 553 void fincstp(); 554 void ffree(const Immediate& index); 555 556 void fsin(); 557 void fcos(); 558 void fptan(); 559 void fprem(); 560 561 void xchgl(Register dst, Register src); 562 void xchgl(Register reg, const Address& address); 563 564 void cmpb(const Address& address, const Immediate& imm); 565 void cmpw(const Address& address, const Immediate& imm); 566 567 void cmpl(Register reg, const Immediate& imm); 568 void cmpl(Register reg0, Register reg1); 569 void cmpl(Register reg, const Address& address); 570 571 void cmpl(const Address& address, Register reg); 572 void cmpl(const Address& address, const Immediate& imm); 573 574 void testl(Register reg1, Register reg2); 575 void testl(Register reg, const Immediate& imm); 576 void testl(Register reg1, const Address& address); 577 578 void testb(const Address& dst, const Immediate& imm); 579 void testl(const Address& dst, const Immediate& imm); 580 581 void andl(Register dst, const Immediate& imm); 582 void andl(Register dst, Register src); 583 void andl(Register dst, const Address& address); 584 585 void orl(Register dst, const Immediate& imm); 586 void orl(Register dst, Register src); 587 void orl(Register dst, const Address& address); 588 589 void xorl(Register dst, Register src); 590 void xorl(Register dst, const Immediate& imm); 591 void xorl(Register dst, const Address& address); 592 593 void addl(Register dst, Register src); 594 void addl(Register reg, const Immediate& imm); 595 void addl(Register reg, const Address& address); 596 597 void addl(const Address& address, Register reg); 598 void addl(const Address& address, const Immediate& imm); 599 600 void adcl(Register dst, Register src); 601 void adcl(Register reg, const Immediate& imm); 602 void adcl(Register dst, const Address& address); 603 604 void subl(Register dst, Register src); 605 void subl(Register reg, const Immediate& imm); 606 void subl(Register reg, const Address& address); 607 void subl(const Address& address, Register src); 608 609 void cdq(); 610 611 void idivl(Register reg); 612 613 void imull(Register dst, Register src); 614 void imull(Register reg, const Immediate& imm); 615 void imull(Register dst, Register src, const Immediate& imm); 616 void imull(Register reg, const Address& address); 617 618 void imull(Register reg); 619 void imull(const Address& address); 620 621 void mull(Register reg); 622 void mull(const Address& address); 623 624 void sbbl(Register dst, Register src); 625 void sbbl(Register reg, const Immediate& imm); 626 void sbbl(Register reg, const Address& address); 627 void sbbl(const Address& address, Register src); 628 629 void incl(Register reg); 630 void incl(const Address& address); 631 632 void decl(Register reg); 633 void decl(const Address& address); 634 635 void shll(Register reg, const Immediate& imm); 636 void shll(Register operand, Register shifter); 637 void shll(const Address& address, const Immediate& imm); 638 void shll(const Address& address, Register shifter); 639 void shrl(Register reg, const Immediate& imm); 640 void shrl(Register operand, Register shifter); 641 void shrl(const Address& address, const Immediate& imm); 642 void shrl(const Address& address, Register shifter); 643 void sarl(Register reg, const Immediate& imm); 644 void sarl(Register operand, Register shifter); 645 void sarl(const Address& address, const Immediate& imm); 646 void sarl(const Address& address, Register shifter); 647 void shld(Register dst, Register src, Register shifter); 648 void shld(Register dst, Register src, const Immediate& imm); 649 void shrd(Register dst, Register src, Register shifter); 650 void shrd(Register dst, Register src, const Immediate& imm); 651 652 void negl(Register reg); 653 void notl(Register reg); 654 655 void enter(const Immediate& imm); 656 void leave(); 657 658 void ret(); 659 void ret(const Immediate& imm); 660 661 void nop(); 662 void int3(); 663 void hlt(); 664 665 void j(Condition condition, Label* label); 666 void j(Condition condition, NearLabel* label); 667 void jecxz(NearLabel* label); 668 669 void jmp(Register reg); 670 void jmp(const Address& address); 671 void jmp(Label* label); 672 void jmp(NearLabel* label); 673 674 void repne_scasb(); 675 void repne_scasw(); 676 void repe_cmpsb(); 677 void repe_cmpsw(); 678 void repe_cmpsl(); 679 void rep_movsb(); 680 void rep_movsw(); 681 682 X86Assembler* lock(); 683 void cmpxchgl(const Address& address, Register reg); 684 void cmpxchg8b(const Address& address); 685 686 void mfence(); 687 688 X86Assembler* fs(); 689 X86Assembler* gs(); 690 691 // 692 // Macros for High-level operations. 693 // 694 695 void AddImmediate(Register reg, const Immediate& imm); 696 697 void LoadLongConstant(XmmRegister dst, int64_t value); 698 void LoadDoubleConstant(XmmRegister dst, double value); 699 700 void LockCmpxchgl(const Address& address, Register reg) { 701 lock()->cmpxchgl(address, reg); 702 } 703 704 void LockCmpxchg8b(const Address& address) { 705 lock()->cmpxchg8b(address); 706 } 707 708 // 709 // Misc. functionality 710 // 711 int PreferredLoopAlignment() { return 16; } 712 void Align(int alignment, int offset); 713 void Bind(Label* label) OVERRIDE; 714 void Jump(Label* label) OVERRIDE { 715 jmp(label); 716 } 717 void Bind(NearLabel* label); 718 719 // 720 // Heap poisoning. 721 // 722 723 // Poison a heap reference contained in `reg`. 724 void PoisonHeapReference(Register reg) { negl(reg); } 725 // Unpoison a heap reference contained in `reg`. 726 void UnpoisonHeapReference(Register reg) { negl(reg); } 727 // Poison a heap reference contained in `reg` if heap poisoning is enabled. 728 void MaybePoisonHeapReference(Register reg) { 729 if (kPoisonHeapReferences) { 730 PoisonHeapReference(reg); 731 } 732 } 733 // Unpoison a heap reference contained in `reg` if heap poisoning is enabled. 734 void MaybeUnpoisonHeapReference(Register reg) { 735 if (kPoisonHeapReferences) { 736 UnpoisonHeapReference(reg); 737 } 738 } 739 740 // Add a double to the constant area, returning the offset into 741 // the constant area where the literal resides. 742 size_t AddDouble(double v) { return constant_area_.AddDouble(v); } 743 744 // Add a float to the constant area, returning the offset into 745 // the constant area where the literal resides. 746 size_t AddFloat(float v) { return constant_area_.AddFloat(v); } 747 748 // Add an int32_t to the constant area, returning the offset into 749 // the constant area where the literal resides. 750 size_t AddInt32(int32_t v) { 751 return constant_area_.AddInt32(v); 752 } 753 754 // Add an int32_t to the end of the constant area, returning the offset into 755 // the constant area where the literal resides. 756 size_t AppendInt32(int32_t v) { 757 return constant_area_.AppendInt32(v); 758 } 759 760 // Add an int64_t to the constant area, returning the offset into 761 // the constant area where the literal resides. 762 size_t AddInt64(int64_t v) { return constant_area_.AddInt64(v); } 763 764 // Add the contents of the constant area to the assembler buffer. 765 void AddConstantArea(); 766 767 // Is the constant area empty? Return true if there are no literals in the constant area. 768 bool IsConstantAreaEmpty() const { return constant_area_.IsEmpty(); } 769 770 // Return the current size of the constant area. 771 size_t ConstantAreaSize() const { return constant_area_.GetSize(); } 772 773 private: 774 inline void EmitUint8(uint8_t value); 775 inline void EmitInt32(int32_t value); 776 inline void EmitRegisterOperand(int rm, int reg); 777 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); 778 inline void EmitFixup(AssemblerFixup* fixup); 779 inline void EmitOperandSizeOverride(); 780 781 void EmitOperand(int rm, const Operand& operand); 782 void EmitImmediate(const Immediate& imm); 783 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); 784 void EmitLabel(Label* label, int instruction_size); 785 void EmitLabelLink(Label* label); 786 void EmitLabelLink(NearLabel* label); 787 788 void EmitGenericShift(int rm, const Operand& operand, const Immediate& imm); 789 void EmitGenericShift(int rm, const Operand& operand, Register shifter); 790 791 ConstantArea constant_area_; 792 793 DISALLOW_COPY_AND_ASSIGN(X86Assembler); 794 }; 795 796 inline void X86Assembler::EmitUint8(uint8_t value) { 797 buffer_.Emit<uint8_t>(value); 798 } 799 800 inline void X86Assembler::EmitInt32(int32_t value) { 801 buffer_.Emit<int32_t>(value); 802 } 803 804 inline void X86Assembler::EmitRegisterOperand(int rm, int reg) { 805 CHECK_GE(rm, 0); 806 CHECK_LT(rm, 8); 807 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg); 808 } 809 810 inline void X86Assembler::EmitXmmRegisterOperand(int rm, XmmRegister reg) { 811 EmitRegisterOperand(rm, static_cast<Register>(reg)); 812 } 813 814 inline void X86Assembler::EmitFixup(AssemblerFixup* fixup) { 815 buffer_.EmitFixup(fixup); 816 } 817 818 inline void X86Assembler::EmitOperandSizeOverride() { 819 EmitUint8(0x66); 820 } 821 822 } // namespace x86 823 } // namespace art 824 825 #endif // ART_COMPILER_UTILS_X86_ASSEMBLER_X86_H_ 826