assembler_x86_64.h revision 3d21bdf8894e780d349c481e5c9e29fe1556051c
1fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko/* 2fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Copyright (C) 2014 The Android Open Source Project 3fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * 4fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Licensed under the Apache License, Version 2.0 (the "License"); 5fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * you may not use this file except in compliance with the License. 6fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * You may obtain a copy of the License at 7fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * 8fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * http://www.apache.org/licenses/LICENSE-2.0 9fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * 10fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Unless required by applicable law or agreed to in writing, software 11fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * distributed under the License is distributed on an "AS IS" BASIS, 12fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * See the License for the specific language governing permissions and 14fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * limitations under the License. 15fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko */ 16fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 17fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#ifndef ART_COMPILER_UTILS_X86_64_ASSEMBLER_X86_64_H_ 18fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#define ART_COMPILER_UTILS_X86_64_ASSEMBLER_X86_64_H_ 19fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 20fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include <vector> 2141b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko 2241b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko#include "base/bit_utils.h" 23fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "base/macros.h" 24fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "constants_x86_64.h" 25fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "globals.h" 26fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "managed_register_x86_64.h" 27fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "offsets.h" 28fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "utils/assembler.h" 29fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 30fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkonamespace art { 31fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkonamespace x86_64 { 32fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 335408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate// Encodes an immediate value for operands. 345408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate// 355408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate// Note: Immediates can be 64b on x86-64 for certain instructions, but are often restricted 365408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate// to 32b. 375408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate// 385408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate// Note: As we support cross-compilation, the value type must be int64_t. Please be aware of 395408b6ba5d73ac0890683ebd7ddb4151a8ac2721avignate// conversion rules in expressions regarding negation, especially size_t on 32b. 40cf7f19135f0e273f7b0136315633c2abfc715343Ian Rogersclass Immediate : public ValueObject { 41fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko public: 42277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe explicit Immediate(int64_t value_in) : value_(value_in) {} 43fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 445a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe int64_t value() const { return value_; } 45fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 46ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_int8() const { return IsInt<8>(value_); } 47ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_uint8() const { return IsUint<8>(value_); } 48ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_int16() const { return IsInt<16>(value_); } 49ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_uint16() const { return IsUint<16>(value_); } 50ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_int32() const { return IsInt<32>(value_); } 51fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 52fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko private: 535a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe const int64_t value_; 54fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}; 55fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 56fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 57cf7f19135f0e273f7b0136315633c2abfc715343Ian Rogersclass Operand : public ValueObject { 58fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko public: 59fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko uint8_t mod() const { 60fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return (encoding_at(0) >> 6) & 3; 61fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 62fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 63fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko Register rm() const { 64fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return static_cast<Register>(encoding_at(0) & 7); 65fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 66fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 67fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko ScaleFactor scale() const { 68fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); 69fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 70fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 71fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko Register index() const { 72fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return static_cast<Register>((encoding_at(1) >> 3) & 7); 73fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 74fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 75fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko Register base() const { 76fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return static_cast<Register>(encoding_at(1) & 7); 77fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 78fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 79790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers uint8_t rex() const { 80790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers return rex_; 81790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers } 82790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers 83fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko int8_t disp8() const { 84fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK_GE(length_, 2); 85fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return static_cast<int8_t>(encoding_[length_ - 1]); 86fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 87fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 88fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko int32_t disp32() const { 89fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK_GE(length_, 5); 90fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko int32_t value; 91fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko memcpy(&value, &encoding_[length_ - 4], sizeof(value)); 92fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return value; 93fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 94fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 95dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers bool IsRegister(CpuRegister reg) const { 96fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. 97790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers && ((encoding_[0] & 0x07) == reg.LowBits()) // Register codes match. 98790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers && (reg.NeedsRex() == ((rex_ & 1) != 0)); // REX.000B bits match. 99fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 100fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 101f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell AssemblerFixup* GetFixup() const { 102f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell return fixup_; 103f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell } 104f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 105fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko protected: 106fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Operand can be sub classed (e.g: Address). 107f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell Operand() : rex_(0), length_(0), fixup_(nullptr) { } 108fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 109277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe void SetModRM(uint8_t mod_in, CpuRegister rm_in) { 110277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_EQ(mod_in & ~3, 0); 111277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe if (rm_in.NeedsRex()) { 112790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers rex_ |= 0x41; // REX.000B 113790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers } 114277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe encoding_[0] = (mod_in << 6) | rm_in.LowBits(); 115fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko length_ = 1; 116fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 117fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 118277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe void SetSIB(ScaleFactor scale_in, CpuRegister index_in, CpuRegister base_in) { 119fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK_EQ(length_, 1); 120277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_EQ(scale_in & ~3, 0); 121277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe if (base_in.NeedsRex()) { 122790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers rex_ |= 0x41; // REX.000B 123790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers } 124277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe if (index_in.NeedsRex()) { 125790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers rex_ |= 0x42; // REX.00X0 126790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers } 127277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe encoding_[1] = (scale_in << 6) | (static_cast<uint8_t>(index_in.LowBits()) << 3) | 128277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe static_cast<uint8_t>(base_in.LowBits()); 129fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko length_ = 2; 130fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 131fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 132fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void SetDisp8(int8_t disp) { 133fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK(length_ == 1 || length_ == 2); 134fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko encoding_[length_++] = static_cast<uint8_t>(disp); 135fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 136fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 137fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void SetDisp32(int32_t disp) { 138fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK(length_ == 1 || length_ == 2); 139fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko int disp_size = sizeof(disp); 140fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko memmove(&encoding_[length_], &disp, disp_size); 141fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko length_ += disp_size; 142fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 143fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 144f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell void SetFixup(AssemblerFixup* fixup) { 145f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell fixup_ = fixup; 146f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell } 147f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 148fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko private: 149790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers uint8_t rex_; 150790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers uint8_t length_; 151790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers uint8_t encoding_[6]; 152f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell AssemblerFixup* fixup_; 153fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 154f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell explicit Operand(CpuRegister reg) : rex_(0), length_(0), fixup_(nullptr) { SetModRM(3, reg); } 155fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 156fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Get the operand encoding byte at the given index. 157277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe uint8_t encoding_at(int index_in) const { 158277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_GE(index_in, 0); 159277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_LT(index_in, length_); 160277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe return encoding_[index_in]; 161fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 162fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 163fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko friend class X86_64Assembler; 164fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}; 165fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 166fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 167fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoclass Address : public Operand { 168fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko public: 169277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(CpuRegister base_in, int32_t disp) { 170277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Init(base_in, disp); 171fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 172fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 173277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(CpuRegister base_in, Offset disp) { 174277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Init(base_in, disp.Int32Value()); 175fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 176fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 177277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(CpuRegister base_in, FrameOffset disp) { 178277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_EQ(base_in.AsRegister(), RSP); 179dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Init(CpuRegister(RSP), disp.Int32Value()); 180fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 181fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 182277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(CpuRegister base_in, MemberOffset disp) { 183277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Init(base_in, disp.Int32Value()); 184fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 185fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 186277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe void Init(CpuRegister base_in, int32_t disp) { 187784cc5c37f382838f89e281758040c6620ccfd01Nicolas Geoffray if (disp == 0 && base_in.LowBits() != RBP) { 188277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetModRM(0, base_in); 189988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray if (base_in.LowBits() == RSP) { 190277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(TIMES_1, CpuRegister(RSP), base_in); 191dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers } 192fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else if (disp >= -128 && disp <= 127) { 193277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetModRM(1, base_in); 194988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray if (base_in.LowBits() == RSP) { 195277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(TIMES_1, CpuRegister(RSP), base_in); 196dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers } 197fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko SetDisp8(disp); 198fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else { 199277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetModRM(2, base_in); 200988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray if (base_in.LowBits() == RSP) { 201277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(TIMES_1, CpuRegister(RSP), base_in); 202dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers } 203fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko SetDisp32(disp); 204fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 205fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 206fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 207fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 208277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(CpuRegister index_in, ScaleFactor scale_in, int32_t disp) { 209277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_NE(index_in.AsRegister(), RSP); // Illegal addressing mode. 210dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetModRM(0, CpuRegister(RSP)); 211277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(scale_in, index_in, CpuRegister(RBP)); 212fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko SetDisp32(disp); 213fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 214fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 215277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(CpuRegister base_in, CpuRegister index_in, ScaleFactor scale_in, int32_t disp) { 216277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_NE(index_in.AsRegister(), RSP); // Illegal addressing mode. 217784cc5c37f382838f89e281758040c6620ccfd01Nicolas Geoffray if (disp == 0 && base_in.LowBits() != RBP) { 218dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetModRM(0, CpuRegister(RSP)); 219277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(scale_in, index_in, base_in); 220fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else if (disp >= -128 && disp <= 127) { 221dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetModRM(1, CpuRegister(RSP)); 222277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(scale_in, index_in, base_in); 223fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko SetDisp8(disp); 224fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else { 225dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetModRM(2, CpuRegister(RSP)); 226277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(scale_in, index_in, base_in); 227fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko SetDisp32(disp); 228fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 229fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 230fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 231dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // If no_rip is true then the Absolute address isn't RIP relative. 23213735955f39b3b304c37d2b2840663c131262c18Ian Rogers static Address Absolute(uintptr_t addr, bool no_rip = false) { 233fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko Address result; 234dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (no_rip) { 235dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers result.SetModRM(0, CpuRegister(RSP)); 236dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers result.SetSIB(TIMES_1, CpuRegister(RSP), CpuRegister(RBP)); 237fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko result.SetDisp32(addr); 238fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else { 23939dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // RIP addressing is done using RBP as the base register. 24039dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // The value in RBP isn't used. Instead the offset is added to RIP. 241dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers result.SetModRM(0, CpuRegister(RBP)); 242fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko result.SetDisp32(addr); 243fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 244fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return result; 245fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 246fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 247f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell // An RIP relative address that will be fixed up later. 248f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell static Address RIP(AssemblerFixup* fixup) { 249f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell Address result; 25039dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // RIP addressing is done using RBP as the base register. 25139dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // The value in RBP isn't used. Instead the offset is added to RIP. 252f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell result.SetModRM(0, CpuRegister(RBP)); 253f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell result.SetDisp32(0); 254f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell result.SetFixup(fixup); 255f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell return result; 256f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell } 257f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 258dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // If no_rip is true then the Absolute address isn't RIP relative. 259dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers static Address Absolute(ThreadOffset<8> addr, bool no_rip = false) { 260dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return Absolute(addr.Int32Value(), no_rip); 261fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 262fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 263fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko private: 264fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko Address() {} 265fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}; 266fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 267fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 268f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell/** 269f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell * Class to handle constant area values. 270f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell */ 271f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendellclass ConstantArea { 272f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell public: 273f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell ConstantArea() {} 274f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 27539dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add a double to the constant area, returning the offset into 27639dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // the constant area where the literal resides. 277f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int AddDouble(double v); 278f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 27939dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add a float to the constant area, returning the offset into 28039dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // the constant area where the literal resides. 281f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int AddFloat(float v); 282f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 28339dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add an int32_t to the constant area, returning the offset into 28439dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // the constant area where the literal resides. 285f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int AddInt32(int32_t v); 286f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 28739dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add an int64_t to the constant area, returning the offset into 28839dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // the constant area where the literal resides. 289f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int AddInt64(int64_t v); 290f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 291f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int GetSize() const { 292f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell return buffer_.size() * elem_size_; 293f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell } 294f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 295f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell const std::vector<int32_t>& GetBuffer() const { 296f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell return buffer_; 297f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell } 298f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 299f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell private: 300f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell static constexpr size_t elem_size_ = sizeof(int32_t); 301f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell std::vector<int32_t> buffer_; 302f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell}; 303f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 304f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 305dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass X86_64Assembler FINAL : public Assembler { 306fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko public: 3078c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky X86_64Assembler() {} 308fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko virtual ~X86_64Assembler() {} 309fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 310fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko /* 311fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Emit Machine Instructions. 312fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko */ 313dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void call(CpuRegister reg); 314fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void call(const Address& address); 315fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void call(Label* label); 316fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 317dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void pushq(CpuRegister reg); 318fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void pushq(const Address& address); 319fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void pushq(const Immediate& imm); 320fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 321dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void popq(CpuRegister reg); 322fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void popq(const Address& address); 323fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 324dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movq(CpuRegister dst, const Immediate& src); 325dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movl(CpuRegister dst, const Immediate& src); 326dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movq(CpuRegister dst, CpuRegister src); 327dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movl(CpuRegister dst, CpuRegister src); 328fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 329dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movq(CpuRegister dst, const Address& src); 330dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movl(CpuRegister dst, const Address& src); 331dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movq(const Address& dst, CpuRegister src); 33240741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void movq(const Address& dst, const Immediate& src); 333dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movl(const Address& dst, CpuRegister src); 334fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void movl(const Address& dst, const Immediate& imm); 335fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 33671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void cmov(Condition c, CpuRegister dst, CpuRegister src); // This is the 64b version. 33771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void cmov(Condition c, CpuRegister dst, CpuRegister src, bool is64bit); 33871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 339dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movzxb(CpuRegister dst, CpuRegister src); 340dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movzxb(CpuRegister dst, const Address& src); 341dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movsxb(CpuRegister dst, CpuRegister src); 342dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movsxb(CpuRegister dst, const Address& src); 343dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movb(CpuRegister dst, const Address& src); 344dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movb(const Address& dst, CpuRegister src); 345dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movb(const Address& dst, const Immediate& imm); 346fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 347dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movzxw(CpuRegister dst, CpuRegister src); 348dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movzxw(CpuRegister dst, const Address& src); 349dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movsxw(CpuRegister dst, CpuRegister src); 350dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movsxw(CpuRegister dst, const Address& src); 351dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movw(CpuRegister dst, const Address& src); 352dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void movw(const Address& dst, CpuRegister src); 35326a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray void movw(const Address& dst, const Immediate& imm); 354fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 355dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void leaq(CpuRegister dst, const Address& src); 356748f140d5f0631780dbeecb033c1416faf78930dNicolas Geoffray void leal(CpuRegister dst, const Address& src); 357fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 3587fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray void movaps(XmmRegister dst, XmmRegister src); 3597fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray 360fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void movss(XmmRegister dst, const Address& src); 361fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void movss(const Address& dst, XmmRegister src); 362fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void movss(XmmRegister dst, XmmRegister src); 363fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 364dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain void movsxd(CpuRegister dst, CpuRegister src); 365dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain void movsxd(CpuRegister dst, const Address& src); 366dff1f2812ecdaea89978c5351f0c70cdabbc0821Roland Levillain 36771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void movd(XmmRegister dst, CpuRegister src); // Note: this is the r64 version, formally movq. 36871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void movd(CpuRegister dst, XmmRegister src); // Note: this is the r64 version, formally movq. 36971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void movd(XmmRegister dst, CpuRegister src, bool is64bit); 37071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void movd(CpuRegister dst, XmmRegister src, bool is64bit); 371fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 372fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void addss(XmmRegister dst, XmmRegister src); 373fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void addss(XmmRegister dst, const Address& src); 374fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void subss(XmmRegister dst, XmmRegister src); 375fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void subss(XmmRegister dst, const Address& src); 376fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void mulss(XmmRegister dst, XmmRegister src); 377fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void mulss(XmmRegister dst, const Address& src); 378fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void divss(XmmRegister dst, XmmRegister src); 379fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void divss(XmmRegister dst, const Address& src); 380fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 381fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void movsd(XmmRegister dst, const Address& src); 382fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void movsd(const Address& dst, XmmRegister src); 383fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void movsd(XmmRegister dst, XmmRegister src); 384fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 385fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void addsd(XmmRegister dst, XmmRegister src); 386fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void addsd(XmmRegister dst, const Address& src); 387fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void subsd(XmmRegister dst, XmmRegister src); 388fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void subsd(XmmRegister dst, const Address& src); 389fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void mulsd(XmmRegister dst, XmmRegister src); 390fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void mulsd(XmmRegister dst, const Address& src); 391fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void divsd(XmmRegister dst, XmmRegister src); 392fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void divsd(XmmRegister dst, const Address& src); 393fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 394851df20225593b10e698a760ac3cd5243620700bAndreas Gampe void cvtsi2ss(XmmRegister dst, CpuRegister src); // Note: this is the r/m32 version. 3956d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain void cvtsi2ss(XmmRegister dst, CpuRegister src, bool is64bit); 39640741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void cvtsi2ss(XmmRegister dst, const Address& src, bool is64bit); 397851df20225593b10e698a760ac3cd5243620700bAndreas Gampe void cvtsi2sd(XmmRegister dst, CpuRegister src); // Note: this is the r/m32 version. 398647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain void cvtsi2sd(XmmRegister dst, CpuRegister src, bool is64bit); 39940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void cvtsi2sd(XmmRegister dst, const Address& src, bool is64bit); 400fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 401851df20225593b10e698a760ac3cd5243620700bAndreas Gampe void cvtss2si(CpuRegister dst, XmmRegister src); // Note: this is the r32 version. 402fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void cvtss2sd(XmmRegister dst, XmmRegister src); 40340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void cvtss2sd(XmmRegister dst, const Address& src); 404fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 405851df20225593b10e698a760ac3cd5243620700bAndreas Gampe void cvtsd2si(CpuRegister dst, XmmRegister src); // Note: this is the r32 version. 406fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void cvtsd2ss(XmmRegister dst, XmmRegister src); 40740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void cvtsd2ss(XmmRegister dst, const Address& src); 408fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 409851df20225593b10e698a760ac3cd5243620700bAndreas Gampe void cvttss2si(CpuRegister dst, XmmRegister src); // Note: this is the r32 version. 410624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain void cvttss2si(CpuRegister dst, XmmRegister src, bool is64bit); 411851df20225593b10e698a760ac3cd5243620700bAndreas Gampe void cvttsd2si(CpuRegister dst, XmmRegister src); // Note: this is the r32 version. 4124c0b61f506644bb6b647be05d02c5fb45b9ceb48Roland Levillain void cvttsd2si(CpuRegister dst, XmmRegister src, bool is64bit); 413fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 414fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void cvtdq2pd(XmmRegister dst, XmmRegister src); 415fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 416fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void comiss(XmmRegister a, XmmRegister b); 41740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void comiss(XmmRegister a, const Address& b); 418fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void comisd(XmmRegister a, XmmRegister b); 41940741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void comisd(XmmRegister a, const Address& b); 420ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle void ucomiss(XmmRegister a, XmmRegister b); 42140741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void ucomiss(XmmRegister a, const Address& b); 422ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle void ucomisd(XmmRegister a, XmmRegister b); 42340741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void ucomisd(XmmRegister a, const Address& b); 424fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 425fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell void roundsd(XmmRegister dst, XmmRegister src, const Immediate& imm); 426fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell void roundss(XmmRegister dst, XmmRegister src, const Immediate& imm); 427fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell 428fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void sqrtsd(XmmRegister dst, XmmRegister src); 429fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void sqrtss(XmmRegister dst, XmmRegister src); 430fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 431fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void xorpd(XmmRegister dst, const Address& src); 432fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void xorpd(XmmRegister dst, XmmRegister src); 433fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void xorps(XmmRegister dst, const Address& src); 434fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void xorps(XmmRegister dst, XmmRegister src); 435fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 436fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void andpd(XmmRegister dst, const Address& src); 43771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void andpd(XmmRegister dst, XmmRegister src); 43871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void andps(XmmRegister dst, XmmRegister src); 43971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 44071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void orpd(XmmRegister dst, XmmRegister src); 44171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void orps(XmmRegister dst, XmmRegister src); 442fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 443fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void flds(const Address& src); 444fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fstps(const Address& dst); 44524f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fsts(const Address& dst); 446fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 447fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fldl(const Address& src); 448fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fstpl(const Address& dst); 44924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fstl(const Address& dst); 45024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell 45124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fstsw(); 45224f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell 45324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fucompp(); 454fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 455fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fnstcw(const Address& dst); 456fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fldcw(const Address& src); 457fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 458fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fistpl(const Address& dst); 459fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fistps(const Address& dst); 460fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fildl(const Address& src); 4610a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain void filds(const Address& src); 462fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 463fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fincstp(); 464fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void ffree(const Immediate& index); 465fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 466fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fsin(); 467fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fcos(); 468fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void fptan(); 46924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fprem(); 470fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 471dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void xchgl(CpuRegister dst, CpuRegister src); 472ecb2f9ba57b08ceac4204ddd6a0a88a0524f8741Nicolas Geoffray void xchgq(CpuRegister dst, CpuRegister src); 473dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void xchgl(CpuRegister reg, const Address& address); 474fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 4753c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray void cmpw(const Address& address, const Immediate& imm); 4763c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray 477dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void cmpl(CpuRegister reg, const Immediate& imm); 478dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void cmpl(CpuRegister reg0, CpuRegister reg1); 479dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void cmpl(CpuRegister reg, const Address& address); 480dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void cmpl(const Address& address, CpuRegister reg); 481fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void cmpl(const Address& address, const Immediate& imm); 482fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 4835a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe void cmpq(CpuRegister reg0, CpuRegister reg1); 48496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray void cmpq(CpuRegister reg0, const Immediate& imm); 48596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray void cmpq(CpuRegister reg0, const Address& address); 486d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle void cmpq(const Address& address, const Immediate& imm); 4875a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe 488dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void testl(CpuRegister reg1, CpuRegister reg2); 489cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle void testl(CpuRegister reg, const Address& address); 490dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void testl(CpuRegister reg, const Immediate& imm); 491fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 492d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle void testq(CpuRegister reg1, CpuRegister reg2); 493f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray void testq(CpuRegister reg, const Address& address); 494f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray 495dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void andl(CpuRegister dst, const Immediate& imm); 496dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void andl(CpuRegister dst, CpuRegister src); 4979574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void andl(CpuRegister reg, const Address& address); 498412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray void andq(CpuRegister dst, const Immediate& imm); 4999574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void andq(CpuRegister dst, CpuRegister src); 50040741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void andq(CpuRegister reg, const Address& address); 501fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 502dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void orl(CpuRegister dst, const Immediate& imm); 503dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void orl(CpuRegister dst, CpuRegister src); 5049574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void orl(CpuRegister reg, const Address& address); 5059574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void orq(CpuRegister dst, CpuRegister src); 5063f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell void orq(CpuRegister dst, const Immediate& imm); 50740741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void orq(CpuRegister reg, const Address& address); 508fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 509dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void xorl(CpuRegister dst, CpuRegister src); 5109574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void xorl(CpuRegister dst, const Immediate& imm); 5119574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void xorl(CpuRegister reg, const Address& address); 5125a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe void xorq(CpuRegister dst, const Immediate& imm); 513412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray void xorq(CpuRegister dst, CpuRegister src); 51440741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void xorq(CpuRegister reg, const Address& address); 515fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 516dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void addl(CpuRegister dst, CpuRegister src); 517dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void addl(CpuRegister reg, const Immediate& imm); 518dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void addl(CpuRegister reg, const Address& address); 519dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void addl(const Address& address, CpuRegister reg); 520fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void addl(const Address& address, const Immediate& imm); 521fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 5225a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe void addq(CpuRegister reg, const Immediate& imm); 5235a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe void addq(CpuRegister dst, CpuRegister src); 52496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray void addq(CpuRegister dst, const Address& address); 5255a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe 526dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void subl(CpuRegister dst, CpuRegister src); 527dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void subl(CpuRegister reg, const Immediate& imm); 528dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void subl(CpuRegister reg, const Address& address); 529fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 5305a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe void subq(CpuRegister reg, const Immediate& imm); 5315a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe void subq(CpuRegister dst, CpuRegister src); 53296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray void subq(CpuRegister dst, const Address& address); 5335a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe 534fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void cdq(); 535d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle void cqo(); 536fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 537dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void idivl(CpuRegister reg); 538d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle void idivq(CpuRegister reg); 539fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 540dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void imull(CpuRegister dst, CpuRegister src); 541dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void imull(CpuRegister reg, const Immediate& imm); 542dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void imull(CpuRegister reg, const Address& address); 543fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 5440f88e87085b7cf6544dadff3f555773966a6853eGuillaume Sanchez void imulq(CpuRegister src); 54534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle void imulq(CpuRegister dst, CpuRegister src); 54634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle void imulq(CpuRegister reg, const Immediate& imm); 54734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle void imulq(CpuRegister reg, const Address& address); 5483f6c7f61855172d3d9b7a9221baba76136088e7cMark Mendell void imulq(CpuRegister dst, CpuRegister reg, const Immediate& imm); 54934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 550dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void imull(CpuRegister reg); 551fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void imull(const Address& address); 552fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 553dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void mull(CpuRegister reg); 554fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void mull(const Address& address); 555fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 556dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void shll(CpuRegister reg, const Immediate& imm); 557dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void shll(CpuRegister operand, CpuRegister shifter); 558dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void shrl(CpuRegister reg, const Immediate& imm); 559dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void shrl(CpuRegister operand, CpuRegister shifter); 560dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void sarl(CpuRegister reg, const Immediate& imm); 561dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void sarl(CpuRegister operand, CpuRegister shifter); 562fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 5639aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle void shlq(CpuRegister reg, const Immediate& imm); 5649aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle void shlq(CpuRegister operand, CpuRegister shifter); 5651a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray void shrq(CpuRegister reg, const Immediate& imm); 5669aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle void shrq(CpuRegister operand, CpuRegister shifter); 5679aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle void sarq(CpuRegister reg, const Immediate& imm); 5689aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle void sarq(CpuRegister operand, CpuRegister shifter); 5691a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray 570dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void negl(CpuRegister reg); 5712e07b4f0a84a7968b4690c2b1be2e2f75cc6fa8eRoland Levillain void negq(CpuRegister reg); 572705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain 573dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void notl(CpuRegister reg); 574705664321a5cc1418255172f92d7d7195cf60a7bRoland Levillain void notq(CpuRegister reg); 575fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 576fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void enter(const Immediate& imm); 577fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void leave(); 578fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 579fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void ret(); 580fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void ret(const Immediate& imm); 581fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 582fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void nop(); 583fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void int3(); 584fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void hlt(); 585fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 586fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void j(Condition condition, Label* label); 587fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 588dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void jmp(CpuRegister reg); 589fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void jmp(const Address& address); 590fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void jmp(Label* label); 591fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 592fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko X86_64Assembler* lock(); 593dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void cmpxchgl(const Address& address, CpuRegister reg); 59458d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell void cmpxchgq(const Address& address, CpuRegister reg); 595fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 596fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void mfence(); 597fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 598fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko X86_64Assembler* gs(); 599fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 6005a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe void setcc(Condition condition, CpuRegister dst); 6015a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe 60271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void bswapl(CpuRegister dst); 60371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe void bswapq(CpuRegister dst); 60471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 60521030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe void repne_scasw(); 60621030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe 607fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // 608fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Macros for High-level operations. 609fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // 610fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 611dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void AddImmediate(CpuRegister reg, const Immediate& imm); 612fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 613fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void LoadDoubleConstant(XmmRegister dst, double value); 614fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 615dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LockCmpxchgl(const Address& address, CpuRegister reg) { 616fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko lock()->cmpxchgl(address, reg); 617fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 618fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 61958d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell void LockCmpxchgq(const Address& address, CpuRegister reg) { 62058d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell lock()->cmpxchgq(address, reg); 62158d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell } 62258d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell 623fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // 624fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Misc. functionality 625fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // 626fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko int PreferredLoopAlignment() { return 16; } 627fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void Align(int alignment, int offset); 628fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void Bind(Label* label); 629fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 630fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // 631fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Overridden common assembler high-level functionality 632fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // 633fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 634fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Emit code that will create an activation on the stack 635dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void BuildFrame(size_t frame_size, ManagedRegister method_reg, 636dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers const std::vector<ManagedRegister>& callee_save_regs, 637dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; 638fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 639fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Emit code that will remove an activation from the stack 640dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs) 641dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OVERRIDE; 642fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 643dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void IncreaseFrameSize(size_t adjust) OVERRIDE; 644dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void DecreaseFrameSize(size_t adjust) OVERRIDE; 645fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 646fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Store routines 647dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Store(FrameOffset offs, ManagedRegister src, size_t size) OVERRIDE; 648dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreRef(FrameOffset dest, ManagedRegister src) OVERRIDE; 649dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreRawPtr(FrameOffset dest, ManagedRegister src) OVERRIDE; 650fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 651dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister scratch) OVERRIDE; 652fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 653dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm, ManagedRegister scratch) 654dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OVERRIDE; 655fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 656dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreStackOffsetToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs, 657dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 658fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 659dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreStackPointerToThread64(ThreadOffset<8> thr_offs) OVERRIDE; 660fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 661dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreSpanning(FrameOffset dest, ManagedRegister src, FrameOffset in_off, 662dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 663fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 664fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Load routines 665dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Load(ManagedRegister dest, FrameOffset src, size_t size) OVERRIDE; 666fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 667dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadFromThread64(ManagedRegister dest, ThreadOffset<8> src, size_t size) OVERRIDE; 668fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 669dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE; 670fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 6713d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier void LoadRef(ManagedRegister dest, ManagedRegister base, MemberOffset offs, 6723d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier bool poison_reference) OVERRIDE; 673fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 674dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs) OVERRIDE; 675fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 676dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadRawPtrFromThread64(ManagedRegister dest, ThreadOffset<8> offs) OVERRIDE; 677fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 678fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Copying routines 679dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Move(ManagedRegister dest, ManagedRegister src, size_t size); 680fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 681dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<8> thr_offs, 682dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 683fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 684dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CopyRawPtrToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs, ManagedRegister scratch) 685dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OVERRIDE; 686fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 687dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch) OVERRIDE; 688fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 689dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch, size_t size) OVERRIDE; 690fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 691dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister scratch, 692dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 693fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 694dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src, ManagedRegister scratch, 695dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 696fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 697dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister scratch, 698dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 699fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 700dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset, 701dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch, size_t size) OVERRIDE; 702fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 703dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset, 704dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch, size_t size) OVERRIDE; 705fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 706dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void MemoryBarrier(ManagedRegister) OVERRIDE; 707fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 708fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Sign extension 709dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE; 710fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 711fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Zero extension 712dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE; 713fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 714fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Exploit fast access in managed code to Thread::Current() 715dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void GetCurrentThread(ManagedRegister tr) OVERRIDE; 716dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void GetCurrentThread(FrameOffset dest_offset, ManagedRegister scratch) OVERRIDE; 717fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 7182cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Set up out_reg to hold a Object** into the handle scope, or to be null if the 719fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // value is null and null_allowed. in_reg holds a possibly stale reference 720eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // that can be used to avoid loading the handle scope entry to see if the value is 7212cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // null. 7222cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier void CreateHandleScopeEntry(ManagedRegister out_reg, FrameOffset handlescope_offset, 7232cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ManagedRegister in_reg, bool null_allowed) OVERRIDE; 724fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 7252cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Set up out_off to hold a Object** into the handle scope, or to be null if the 726fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // value is null and null_allowed. 7272cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier void CreateHandleScopeEntry(FrameOffset out_off, FrameOffset handlescope_offset, 7282cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ManagedRegister scratch, bool null_allowed) OVERRIDE; 729fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 730eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // src holds a handle scope entry (Object**) load this into dst 731eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier virtual void LoadReferenceFromHandleScope(ManagedRegister dst, 732fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko ManagedRegister src); 733fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 734fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Heap::VerifyObject on src. In some cases (such as a reference to this) we 735fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // know that src may not be null. 736dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE; 737dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE; 738fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 739fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Call to address held at [base+offset] 740dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Call(ManagedRegister base, Offset offset, ManagedRegister scratch) OVERRIDE; 741dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Call(FrameOffset base, Offset offset, ManagedRegister scratch) OVERRIDE; 742dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CallFromThread64(ThreadOffset<8> offset, ManagedRegister scratch) OVERRIDE; 743fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 744fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // Generate code to check if Thread::Current()->exception_ is non-null 745fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko // and branch to a ExceptionSlowPath if it is. 746dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void ExceptionPoll(ManagedRegister scratch, size_t stack_adjust) OVERRIDE; 747fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 74839dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add a double to the constant area, returning the offset into 74939dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // the constant area where the literal resides. 750f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int AddDouble(double v) { return constant_area_.AddDouble(v); } 751f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 75239dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add a float to the constant area, returning the offset into 75339dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // the constant area where the literal resides. 754f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int AddFloat(float v) { return constant_area_.AddFloat(v); } 755f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 75639dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add an int32_t to the constant area, returning the offset into 75739dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // the constant area where the literal resides. 758f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int AddInt32(int32_t v) { return constant_area_.AddInt32(v); } 759f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 76039dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add an int64_t to the constant area, returning the offset into 76139dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // the constant area where the literal resides. 762f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell int AddInt64(int64_t v) { return constant_area_.AddInt64(v); } 763f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 76439dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Add the contents of the constant area to the assembler buffer. 765f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell void AddConstantArea(); 766f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 76739dcf55a56da746e04f477f89e7b00ba1de03880Mark Mendell // Is the constant area empty? Return true if there are no literals in the constant area. 768f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell bool IsConstantAreaEmpty() const { return constant_area_.GetSize() == 0; } 769f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 770fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko private: 771dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitUint8(uint8_t value); 772dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitInt32(int32_t value); 7735a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe void EmitInt64(int64_t value); 774dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitRegisterOperand(uint8_t rm, uint8_t reg); 775dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitXmmRegisterOperand(uint8_t rm, XmmRegister reg); 776dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitFixup(AssemblerFixup* fixup); 777dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOperandSizeOverride(); 778dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 779dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOperand(uint8_t rm, const Operand& operand); 780fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void EmitImmediate(const Immediate& imm); 781dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitComplex(uint8_t rm, const Operand& operand, const Immediate& immediate); 782fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void EmitLabel(Label* label, int instruction_size); 783fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void EmitLabelLink(Label* label); 784fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko void EmitNearLabelLink(Label* label); 785fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 7861a43dd78d054dbad8d7af9ba4829ea2f1cb70b53Nicolas Geoffray void EmitGenericShift(bool wide, int rm, CpuRegister reg, const Immediate& imm); 7879aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle void EmitGenericShift(bool wide, int rm, CpuRegister operand, CpuRegister shifter); 788dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 789dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // If any input is not false, output the necessary rex prefix. 790dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex(bool force, bool w, bool r, bool x, bool b); 791dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 792dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Emit a rex prefix byte if necessary for reg. ie if reg is a register in the range R8 to R15. 793dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex32(CpuRegister reg); 794dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex32(CpuRegister dst, CpuRegister src); 795dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex32(XmmRegister dst, XmmRegister src); 796dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex32(CpuRegister dst, XmmRegister src); 797dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex32(XmmRegister dst, CpuRegister src); 798dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex32(const Operand& operand); 799dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex32(CpuRegister dst, const Operand& operand); 800dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalRex32(XmmRegister dst, const Operand& operand); 801dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 802dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Emit a REX.W prefix plus necessary register bit encodings. 803d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle void EmitRex64(); 804dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitRex64(CpuRegister reg); 805d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13Calin Juravle void EmitRex64(const Operand& operand); 806dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitRex64(CpuRegister dst, CpuRegister src); 807dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitRex64(CpuRegister dst, const Operand& operand); 80840741f394b2737e503f2c08be0ae9dd490fb106bMark Mendell void EmitRex64(XmmRegister dst, const Operand& operand); 809102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray void EmitRex64(XmmRegister dst, CpuRegister src); 810624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain void EmitRex64(CpuRegister dst, XmmRegister src); 811dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 812dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Emit a REX prefix to normalize byte registers plus necessary register bit encodings. 813dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalByteRegNormalizingRex32(CpuRegister dst, CpuRegister src); 814dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void EmitOptionalByteRegNormalizingRex32(CpuRegister dst, const Operand& operand); 815fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 816f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell ConstantArea constant_area_; 817f55c3e0825cdfc4c5a27730031177d1a0198ec5aMark Mendell 818fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko DISALLOW_COPY_AND_ASSIGN(X86_64Assembler); 819fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}; 820fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 821fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoinline void X86_64Assembler::EmitUint8(uint8_t value) { 822fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko buffer_.Emit<uint8_t>(value); 823fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 824fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 825fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoinline void X86_64Assembler::EmitInt32(int32_t value) { 826fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko buffer_.Emit<int32_t>(value); 827fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 828fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 8295a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampeinline void X86_64Assembler::EmitInt64(int64_t value) { 83055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain // Write this 64-bit value as two 32-bit words for alignment reasons 83155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain // (this is essentially when running on ARM, which does not allow 83255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain // 64-bit unaligned accesses). We assume little-endianness here. 83355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain EmitInt32(Low32Bits(value)); 83455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain EmitInt32(High32Bits(value)); 8355a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe} 8365a4fa82ab42af6e728a60e3261963aa243c3e2cdAndreas Gampe 837dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersinline void X86_64Assembler::EmitRegisterOperand(uint8_t rm, uint8_t reg) { 838fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK_GE(rm, 0); 839fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK_LT(rm, 8); 840102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray buffer_.Emit<uint8_t>((0xC0 | (reg & 7)) + (rm << 3)); 841fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 842fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 843dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersinline void X86_64Assembler::EmitXmmRegisterOperand(uint8_t rm, XmmRegister reg) { 844dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EmitRegisterOperand(rm, static_cast<uint8_t>(reg.AsFloatRegister())); 845fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 846fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 847fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoinline void X86_64Assembler::EmitFixup(AssemblerFixup* fixup) { 848fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko buffer_.EmitFixup(fixup); 849fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 850fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 851fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoinline void X86_64Assembler::EmitOperandSizeOverride() { 852fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko EmitUint8(0x66); 853fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 854fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 855fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} // namespace x86_64 856fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} // namespace art 857fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 858fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#endif // ART_COMPILER_UTILS_X86_64_ASSEMBLER_X86_64_H_ 859