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