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