12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 17166db04e259ca51838c311891598664deeed85adIan Rogers#ifndef ART_COMPILER_UTILS_X86_ASSEMBLER_X86_H_ 18166db04e259ca51838c311891598664deeed85adIan Rogers#define ART_COMPILER_UTILS_X86_ASSEMBLER_X86_H_ 19a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 200d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers#include <vector> 21d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko 22d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko#include "base/arena_containers.h" 2380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/bit_utils.h" 24761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 250f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "constants_x86.h" 26578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h" 272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "managed_register_x86.h" 28578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h" 29d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko#include "utils/array_ref.h" 30166db04e259ca51838c311891598664deeed85adIan Rogers#include "utils/assembler.h" 31a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 326b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art { 332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace x86 { 34a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 35cf7f19135f0e273f7b0136315633c2abfc715343Ian Rogersclass Immediate : public ValueObject { 36a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro public: 37277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe explicit Immediate(int32_t value_in) : value_(value_in) {} 38a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 39a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro int32_t value() const { return value_; } 40a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 41ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_int8() const { return IsInt<8>(value_); } 42ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_uint8() const { return IsUint<8>(value_); } 43ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_int16() const { return IsInt<16>(value_); } 44ab1eb0d1d047e3478ebb891e5259d2f1d1dd78bdAndreas Gampe bool is_uint16() const { return IsUint<16>(value_); } 45a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 46a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro private: 47a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro const int32_t value_; 48a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}; 49a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 50a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 51cf7f19135f0e273f7b0136315633c2abfc715343Ian Rogersclass Operand : public ValueObject { 52a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro public: 53a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro uint8_t mod() const { 54a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro return (encoding_at(0) >> 6) & 3; 55a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 56a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 57a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro Register rm() const { 58a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro return static_cast<Register>(encoding_at(0) & 7); 59a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 60a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 61a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro ScaleFactor scale() const { 62a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); 63a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 64a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 65a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro Register index() const { 66a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro return static_cast<Register>((encoding_at(1) >> 3) & 7); 67a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 68a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 69a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro Register base() const { 70a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro return static_cast<Register>(encoding_at(1) & 7); 71a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 72a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 73a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro int8_t disp8() const { 74a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro CHECK_GE(length_, 2); 75a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro return static_cast<int8_t>(encoding_[length_ - 1]); 76a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 77a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 78a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro int32_t disp32() const { 79a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro CHECK_GE(length_, 5); 80a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro int32_t value; 81a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro memcpy(&value, &encoding_[length_ - 4], sizeof(value)); 82a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro return value; 83a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 84a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 85a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro bool IsRegister(Register reg) const { 86a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. 87a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro && ((encoding_[0] & 0x07) == reg); // Register codes match. 88a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 89a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 90a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro protected: 91a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro // Operand can be sub classed (e.g: Address). 920616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell Operand() : length_(0), fixup_(nullptr) { } 93a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 94277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe void SetModRM(int mod_in, Register rm_in) { 95277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_EQ(mod_in & ~3, 0); 96277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe encoding_[0] = (mod_in << 6) | rm_in; 97a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro length_ = 1; 98a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 99a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 100277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe void SetSIB(ScaleFactor scale_in, Register index_in, Register base_in) { 101a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro CHECK_EQ(length_, 1); 102277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_EQ(scale_in & ~3, 0); 103277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe encoding_[1] = (scale_in << 6) | (index_in << 3) | base_in; 104a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro length_ = 2; 105a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 106a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 107a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void SetDisp8(int8_t disp) { 108a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro CHECK(length_ == 1 || length_ == 2); 109a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro encoding_[length_++] = static_cast<uint8_t>(disp); 110a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 111a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 112a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void SetDisp32(int32_t disp) { 113a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro CHECK(length_ == 1 || length_ == 2); 114a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro int disp_size = sizeof(disp); 115a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro memmove(&encoding_[length_], &disp, disp_size); 116a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro length_ += disp_size; 117a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 118a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 1190616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell AssemblerFixup* GetFixup() const { 1200616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell return fixup_; 1210616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell } 1220616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 1230616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell void SetFixup(AssemblerFixup* fixup) { 1240616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell fixup_ = fixup; 1250616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell } 1260616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 127a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro private: 12813735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t length_; 12913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t encoding_[6]; 130a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 1310616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // A fixup can be associated with the operand, in order to be applied after the 1320616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // code has been generated. This is used for constant area fixups. 1330616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell AssemblerFixup* fixup_; 1340616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 1350616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell explicit Operand(Register reg) : fixup_(nullptr) { SetModRM(3, reg); } 136a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 137a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro // Get the operand encoding byte at the given index. 138277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe uint8_t encoding_at(int index_in) const { 139277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_GE(index_in, 0); 140277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_LT(index_in, length_); 141277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe return encoding_[index_in]; 142a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 143a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 1442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers friend class X86Assembler; 145a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}; 146a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 147a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 148a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroclass Address : public Operand { 149a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro public: 150277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(Register base_in, int32_t disp) { 151277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Init(base_in, disp); 152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1540616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell Address(Register base_in, int32_t disp, AssemblerFixup *fixup) { 1550616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell Init(base_in, disp); 1560616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell SetFixup(fixup); 1570616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell } 1580616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 159277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(Register base_in, Offset disp) { 160277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Init(base_in, disp.Int32Value()); 161a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers } 162a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers 163277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(Register base_in, FrameOffset disp) { 164277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_EQ(base_in, ESP); 165b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Init(ESP, disp.Int32Value()); 166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 168277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Address(Register base_in, MemberOffset disp) { 169277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe Init(base_in, disp.Int32Value()); 170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 172805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell Address(Register index_in, ScaleFactor scale_in, int32_t disp) { 173805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell CHECK_NE(index_in, ESP); // Illegal addressing mode. 174805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell SetModRM(0, ESP); 175805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell SetSIB(scale_in, index_in, EBP); 176805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell SetDisp32(disp); 177805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell } 178805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 179805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell Address(Register base_in, Register index_in, ScaleFactor scale_in, int32_t disp) { 180805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell Init(base_in, index_in, scale_in, disp); 181805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell } 182805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 183805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell Address(Register base_in, 184805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell Register index_in, 185805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell ScaleFactor scale_in, 186805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell int32_t disp, AssemblerFixup *fixup) { 187805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell Init(base_in, index_in, scale_in, disp); 188805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell SetFixup(fixup); 189805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell } 190805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 191805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell static Address Absolute(uintptr_t addr) { 192805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell Address result; 193805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell result.SetModRM(0, EBP); 194805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell result.SetDisp32(addr); 195805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell return result; 196805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell } 197805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 198805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell static Address Absolute(ThreadOffset<4> addr) { 199805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell return Absolute(addr.Int32Value()); 200805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell } 201805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 202805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell private: 203805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell Address() {} 204805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 205277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe void Init(Register base_in, int32_t disp) { 206277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe if (disp == 0 && base_in != EBP) { 207277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetModRM(0, base_in); 208277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe if (base_in == ESP) SetSIB(TIMES_1, ESP, base_in); 209a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } else if (disp >= -128 && disp <= 127) { 210277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetModRM(1, base_in); 211277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe if (base_in == ESP) SetSIB(TIMES_1, ESP, base_in); 212a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro SetDisp8(disp); 213a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } else { 214277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetModRM(2, base_in); 215277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe if (base_in == ESP) SetSIB(TIMES_1, ESP, base_in); 216a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro SetDisp32(disp); 217a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 218a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 219a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 220805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell void Init(Register base_in, Register index_in, ScaleFactor scale_in, int32_t disp) { 221277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe CHECK_NE(index_in, ESP); // Illegal addressing mode. 222277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe if (disp == 0 && base_in != EBP) { 223a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro SetModRM(0, ESP); 224277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(scale_in, index_in, base_in); 225a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } else if (disp >= -128 && disp <= 127) { 226a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro SetModRM(1, ESP); 227277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(scale_in, index_in, base_in); 228a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro SetDisp8(disp); 229a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } else { 230a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro SetModRM(2, ESP); 231277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe SetSIB(scale_in, index_in, base_in); 232a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro SetDisp32(disp); 233a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 234a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro } 235a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}; 236a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 237a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 23873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell// This is equivalent to the Label class, used in a slightly different context. We 23973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell// inherit the functionality of the Label class, but prevent unintended 24073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell// derived-to-base conversions by making the base class private. 24173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendellclass NearLabel : private Label { 24273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell public: 24373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell NearLabel() : Label() {} 24473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell 24573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell // Expose the Label routines that we need. 24673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell using Label::Position; 24773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell using Label::LinkPosition; 24873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell using Label::IsBound; 24973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell using Label::IsUnused; 25073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell using Label::IsLinked; 25173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell 25273f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell private: 25373f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell using Label::BindTo; 25473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell using Label::LinkTo; 25573f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell 25673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell friend class x86::X86Assembler; 25773f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell 25873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell DISALLOW_COPY_AND_ASSIGN(NearLabel); 25973f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell}; 26073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell 2610616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell/** 2620616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell * Class to handle constant area values. 2630616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell */ 2640616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendellclass ConstantArea { 2650616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell public: 266d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko explicit ConstantArea(ArenaAllocator* arena) : buffer_(arena->Adapter(kArenaAllocAssembler)) {} 2670616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 2680616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add a double to the constant area, returning the offset into 2690616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // the constant area where the literal resides. 270805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AddDouble(double v); 2710616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 2720616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add a float to the constant area, returning the offset into 2730616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // the constant area where the literal resides. 274805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AddFloat(float v); 2750616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 2760616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add an int32_t to the constant area, returning the offset into 2770616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // the constant area where the literal resides. 278805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AddInt32(int32_t v); 279805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 280805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell // Add an int32_t to the end of the constant area, returning the offset into 281805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell // the constant area where the literal resides. 282805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AppendInt32(int32_t v); 2830616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 2840616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add an int64_t to the constant area, returning the offset into 2850616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // the constant area where the literal resides. 286805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AddInt64(int64_t v); 2870616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 2880616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell bool IsEmpty() const { 2890616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell return buffer_.size() == 0; 2900616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell } 2910616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 292805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t GetSize() const { 293805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell return buffer_.size() * elem_size_; 2940616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell } 2950616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 296d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko ArrayRef<const int32_t> GetBuffer() const { 297d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko return ArrayRef<const int32_t>(buffer_); 2980616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell } 2990616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 3000616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell private: 301805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell static constexpr size_t elem_size_ = sizeof(int32_t); 302d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko ArenaVector<int32_t> buffer_; 3030616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell}; 30473f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell 305befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogersclass X86Assembler FINAL : public Assembler { 306a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro public: 307d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko explicit X86Assembler(ArenaAllocator* arena) : Assembler(arena), constant_area_(arena) {} 3082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers virtual ~X86Assembler() {} 309c143c55718342519db5398e41dda31422cf16c79buzbee 310a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro /* 311a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro * Emit Machine Instructions. 312a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro */ 313a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void call(Register reg); 314a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void call(const Address& address); 315a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void call(Label* label); 3168ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray void call(const ExternalLabel& label); 317a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 318a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void pushl(Register reg); 319a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void pushl(const Address& address); 320a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void pushl(const Immediate& imm); 321a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 322a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void popl(Register reg); 323a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void popl(const Address& address); 324a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 325a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movl(Register dst, const Immediate& src); 326a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movl(Register dst, Register src); 327a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 328a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movl(Register dst, const Address& src); 329a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movl(const Address& dst, Register src); 330a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movl(const Address& dst, const Immediate& imm); 331bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers void movl(const Address& dst, Label* lbl); 332a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 3337a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell void movntl(const Address& dst, Register src); 3347a08fb53bd13c74dec92256bef22a37250db1373Mark Mendell 33509ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell void bswapl(Register dst); 336c39dac148cce137ffd78a8e43499fba10c5c79e0Aart Bik 337bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell void bsfl(Register dst, Register src); 338bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell void bsfl(Register dst, const Address& src); 3398ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell void bsrl(Register dst, Register src); 3408ae3ffb29489a127f2a6242c33845dac8d50e508Mark Mendell void bsrl(Register dst, const Address& src); 34109ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell 342c39dac148cce137ffd78a8e43499fba10c5c79e0Aart Bik void popcntl(Register dst, Register src); 343c39dac148cce137ffd78a8e43499fba10c5c79e0Aart Bik void popcntl(Register dst, const Address& src); 344c39dac148cce137ffd78a8e43499fba10c5c79e0Aart Bik 345bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell void rorl(Register reg, const Immediate& imm); 346bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell void rorl(Register operand, Register shifter); 347bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell void roll(Register reg, const Immediate& imm); 348bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell void roll(Register operand, Register shifter); 349bcee092d7b0cbb7181d428115ad98d25ce844061Mark Mendell 350a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movzxb(Register dst, ByteRegister src); 351a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movzxb(Register dst, const Address& src); 352a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movsxb(Register dst, ByteRegister src); 353a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movsxb(Register dst, const Address& src); 354a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movb(Register dst, const Address& src); 355a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movb(const Address& dst, ByteRegister src); 356a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movb(const Address& dst, const Immediate& imm); 357a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 358a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movzxw(Register dst, Register src); 359a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movzxw(Register dst, const Address& src); 360a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movsxw(Register dst, Register src); 361a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movsxw(Register dst, const Address& src); 362a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movw(Register dst, const Address& src); 363a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movw(const Address& dst, Register src); 36426a25ef62a13f409f941aa39825a51b4d6f0f047Nicolas Geoffray void movw(const Address& dst, const Immediate& imm); 365a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 366a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void leal(Register dst, const Address& src); 367a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 368b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void cmovl(Condition condition, Register dst, Register src); 369abdac47c3c471d034a5b81aec35bf4201ba86a88Mark Mendell void cmovl(Condition condition, Register dst, const Address& src); 370b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 3715b4b898ed8725242ee6b7229b94467c3ea3054c8Nicolas Geoffray void setb(Condition condition, Register dst); 372a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 3737fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray void movaps(XmmRegister dst, XmmRegister src); 374a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movss(XmmRegister dst, const Address& src); 375a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movss(const Address& dst, XmmRegister src); 376a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movss(XmmRegister dst, XmmRegister src); 377a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 378a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movd(XmmRegister dst, Register src); 379a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movd(Register dst, XmmRegister src); 380a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 381a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addss(XmmRegister dst, XmmRegister src); 382a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addss(XmmRegister dst, const Address& src); 383a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void subss(XmmRegister dst, XmmRegister src); 384a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void subss(XmmRegister dst, const Address& src); 385a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void mulss(XmmRegister dst, XmmRegister src); 386a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void mulss(XmmRegister dst, const Address& src); 387a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void divss(XmmRegister dst, XmmRegister src); 388a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void divss(XmmRegister dst, const Address& src); 389a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 390a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movsd(XmmRegister dst, const Address& src); 391a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movsd(const Address& dst, XmmRegister src); 392a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void movsd(XmmRegister dst, XmmRegister src); 393a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 39452c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle void psrlq(XmmRegister reg, const Immediate& shift_count); 39552c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle void punpckldq(XmmRegister dst, XmmRegister src); 39652c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle 397234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray void movhpd(XmmRegister dst, const Address& src); 398234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray void movhpd(const Address& dst, XmmRegister src); 399234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray 400234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray void psrldq(XmmRegister reg, const Immediate& shift_count); 401234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray 402a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addsd(XmmRegister dst, XmmRegister src); 403a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addsd(XmmRegister dst, const Address& src); 404a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void subsd(XmmRegister dst, XmmRegister src); 405a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void subsd(XmmRegister dst, const Address& src); 406a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void mulsd(XmmRegister dst, XmmRegister src); 407a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void mulsd(XmmRegister dst, const Address& src); 408a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void divsd(XmmRegister dst, XmmRegister src); 409a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void divsd(XmmRegister dst, const Address& src); 410a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 411a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvtsi2ss(XmmRegister dst, Register src); 412a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvtsi2sd(XmmRegister dst, Register src); 413a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 414a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvtss2si(Register dst, XmmRegister src); 415a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvtss2sd(XmmRegister dst, XmmRegister src); 416a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 417a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvtsd2si(Register dst, XmmRegister src); 418a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvtsd2ss(XmmRegister dst, XmmRegister src); 419a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 420a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvttss2si(Register dst, XmmRegister src); 421a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvttsd2si(Register dst, XmmRegister src); 422a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 423a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cvtdq2pd(XmmRegister dst, XmmRegister src); 424a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 425a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void comiss(XmmRegister a, XmmRegister b); 426a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void comisd(XmmRegister a, XmmRegister b); 427ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle void ucomiss(XmmRegister a, XmmRegister b); 4289f51f26b815fb955a3b91df86d54acd3f41480e4Mark Mendell void ucomiss(XmmRegister a, const Address& b); 429ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle void ucomisd(XmmRegister a, XmmRegister b); 4309f51f26b815fb955a3b91df86d54acd3f41480e4Mark Mendell void ucomisd(XmmRegister a, const Address& b); 431a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 432fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell void roundsd(XmmRegister dst, XmmRegister src, const Immediate& imm); 433fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell void roundss(XmmRegister dst, XmmRegister src, const Immediate& imm); 434fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell 435a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void sqrtsd(XmmRegister dst, XmmRegister src); 436a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void sqrtss(XmmRegister dst, XmmRegister src); 437a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 438a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void xorpd(XmmRegister dst, const Address& src); 439a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void xorpd(XmmRegister dst, XmmRegister src); 440a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void xorps(XmmRegister dst, const Address& src); 441a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void xorps(XmmRegister dst, XmmRegister src); 442a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 44309ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell void andpd(XmmRegister dst, XmmRegister src); 444a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void andpd(XmmRegister dst, const Address& src); 44509ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell void andps(XmmRegister dst, XmmRegister src); 44609ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell void andps(XmmRegister dst, const Address& src); 44709ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell 44809ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell void orpd(XmmRegister dst, XmmRegister src); 44909ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell void orps(XmmRegister dst, XmmRegister src); 450a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 451a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void flds(const Address& src); 452a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fstps(const Address& dst); 45324f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fsts(const Address& dst); 454a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 455a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fldl(const Address& src); 456a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fstpl(const Address& dst); 45724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fstl(const Address& dst); 45824f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell 45924f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fstsw(); 46024f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell 46124f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fucompp(); 462a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 463a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fnstcw(const Address& dst); 464a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fldcw(const Address& src); 465a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 466a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fistpl(const Address& dst); 467a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fistps(const Address& dst); 468a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fildl(const Address& src); 4690a18601f141d864a26d4b74ff5613e69ae411483Roland Levillain void filds(const Address& src); 470a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 471a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fincstp(); 472a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void ffree(const Immediate& index); 473a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 474a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fsin(); 475a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fcos(); 476a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void fptan(); 47724f2dfae084b2382c053f5d688fd6bb26cb8a328Mark Mendell void fprem(); 478a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 479a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void xchgl(Register dst, Register src); 4807caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers void xchgl(Register reg, const Address& address); 481a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 4823c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray void cmpw(const Address& address, const Immediate& imm); 4833c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray 484a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cmpl(Register reg, const Immediate& imm); 485a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cmpl(Register reg0, Register reg1); 486a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cmpl(Register reg, const Address& address); 487a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 488a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cmpl(const Address& address, Register reg); 489a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cmpl(const Address& address, const Immediate& imm); 490a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 491a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void testl(Register reg1, Register reg2); 492a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void testl(Register reg, const Immediate& imm); 493f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray void testl(Register reg1, const Address& address); 494a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 495a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void andl(Register dst, const Immediate& imm); 496a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void andl(Register dst, Register src); 4979574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void andl(Register dst, const Address& address); 498a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 499a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void orl(Register dst, const Immediate& imm); 500a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void orl(Register dst, Register src); 5019574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void orl(Register dst, const Address& address); 502a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 503a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void xorl(Register dst, Register src); 504b55f835d66a61e5da6fc1895ba5a0482868c9552Nicolas Geoffray void xorl(Register dst, const Immediate& imm); 5059574c4b5f5ef039d694ac12c97e25ca02eca83c0Nicolas Geoffray void xorl(Register dst, const Address& address); 506a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 507a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addl(Register dst, Register src); 508a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addl(Register reg, const Immediate& imm); 509a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addl(Register reg, const Address& address); 510a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 511a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addl(const Address& address, Register reg); 512a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void addl(const Address& address, const Immediate& imm); 513a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 514a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void adcl(Register dst, Register src); 515a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void adcl(Register reg, const Immediate& imm); 516a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void adcl(Register dst, const Address& address); 517a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 518a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void subl(Register dst, Register src); 519a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void subl(Register reg, const Immediate& imm); 520a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void subl(Register reg, const Address& address); 52109ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell void subl(const Address& address, Register src); 522a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 523a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cdq(); 524a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 525a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void idivl(Register reg); 526a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 527a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void imull(Register dst, Register src); 528a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void imull(Register reg, const Immediate& imm); 5294a2aa4af61e653a89f88d776dcdc55f6c7ca05f2Mark Mendell void imull(Register dst, Register src, const Immediate& imm); 530a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void imull(Register reg, const Address& address); 531a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 532a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void imull(Register reg); 533a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void imull(const Address& address); 534a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 535a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void mull(Register reg); 536a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void mull(const Address& address); 537a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 538a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void sbbl(Register dst, Register src); 539a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void sbbl(Register reg, const Immediate& imm); 540a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void sbbl(Register reg, const Address& address); 54109ed1a3125849ec6ac07cb886e3c502e1dcfada2Mark Mendell void sbbl(const Address& address, Register src); 542a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 543a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void incl(Register reg); 544a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void incl(const Address& address); 545a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 546a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void decl(Register reg); 547a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void decl(const Address& address); 548a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 549a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void shll(Register reg, const Immediate& imm); 550a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void shll(Register operand, Register shifter); 5517394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void shll(const Address& address, const Immediate& imm); 5527394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void shll(const Address& address, Register shifter); 553a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void shrl(Register reg, const Immediate& imm); 554a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void shrl(Register operand, Register shifter); 5557394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void shrl(const Address& address, const Immediate& imm); 5567394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void shrl(const Address& address, Register shifter); 557a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void sarl(Register reg, const Immediate& imm); 558a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void sarl(Register operand, Register shifter); 5597394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void sarl(const Address& address, const Immediate& imm); 5607394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void sarl(const Address& address, Register shifter); 5619aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle void shld(Register dst, Register src, Register shifter); 5627394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void shld(Register dst, Register src, const Immediate& imm); 5639aec02fc5df5518c16f1e5a9b6cb198a192db973Calin Juravle void shrd(Register dst, Register src, Register shifter); 5647394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void shrd(Register dst, Register src, const Immediate& imm); 565a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 566a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void negl(Register reg); 567a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void notl(Register reg); 568a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 569a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void enter(const Immediate& imm); 570a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void leave(); 571a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 572a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void ret(); 573a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void ret(const Immediate& imm); 574a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 575a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void nop(); 576a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void int3(); 577a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void hlt(); 578a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 579a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void j(Condition condition, Label* label); 58073f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell void j(Condition condition, NearLabel* label); 58173f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell void jecxz(NearLabel* label); 582a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 583a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void jmp(Register reg); 5847caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers void jmp(const Address& address); 585a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void jmp(Label* label); 58673f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell void jmp(NearLabel* label); 587a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 58821030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe void repne_scasw(); 58971311f868e2579fa5d40b24e620198734119d1a0agicsaki void repe_cmpsw(); 590970abfb65530b700f3a0cc8b90b131df5420cec3agicsaki void repe_cmpsl(); 591b9c4bbee9364a9351376fd1fec9604e7c84778d8Mark Mendell void rep_movsw(); 59221030dd59b1e350f6f43de39e3c4ce0886ff539cAndreas Gampe 5932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers X86Assembler* lock(); 594a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void cmpxchgl(const Address& address, Register reg); 59558d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell void cmpxchg8b(const Address& address); 596a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 59779ab9e32c6880e7b342c192a479c858c9dccf496Elliott Hughes void mfence(); 59879ab9e32c6880e7b342c192a479c858c9dccf496Elliott Hughes 5992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers X86Assembler* fs(); 600befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers X86Assembler* gs(); 601b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 602b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // 603b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Macros for High-level operations. 604b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // 605b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 6062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers void AddImmediate(Register reg, const Immediate& imm); 607b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 608647b9ed41cdb7cf302fd356627a3ba372419b78cRoland Levillain void LoadLongConstant(XmmRegister dst, int64_t value); 6092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers void LoadDoubleConstant(XmmRegister dst, double value); 610b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 6112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers void LockCmpxchgl(const Address& address, Register reg) { 6122c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers lock()->cmpxchgl(address, reg); 6132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 614b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 61558d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell void LockCmpxchg8b(const Address& address) { 61658d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell lock()->cmpxchg8b(address); 61758d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell } 61858d25fd052e999a24734b0cf856a1563e3d1b2d0Mark Mendell 6192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 6202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // Misc. functionality 6212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 6222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int PreferredLoopAlignment() { return 16; } 6232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers void Align(int alignment, int offset); 62485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe void Bind(Label* label) OVERRIDE; 62585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe void Jump(Label* label) OVERRIDE { 62685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe jmp(label); 62785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 62873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell void Bind(NearLabel* label); 629b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 6302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 6312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // Overridden common assembler high-level functionality 6322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 633b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 6342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 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; 638b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 6392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 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; 64245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 643dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void IncreaseFrameSize(size_t adjust) OVERRIDE; 644dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void DecreaseFrameSize(size_t adjust) OVERRIDE; 645b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 6462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 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; 650b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 651dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister scratch) OVERRIDE; 652b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 653dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreImmediateToThread32(ThreadOffset<4> dest, uint32_t imm, ManagedRegister scratch) 654dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OVERRIDE; 655b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 656dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreStackOffsetToThread32(ThreadOffset<4> thr_offs, FrameOffset fr_offs, 657dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 658b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 659dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreStackPointerToThread32(ThreadOffset<4> thr_offs) OVERRIDE; 660bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 661dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreSpanning(FrameOffset dest, ManagedRegister src, FrameOffset in_off, 662dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 663668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao 6642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // Load routines 665dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Load(ManagedRegister dest, FrameOffset src, size_t size) OVERRIDE; 666b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 667dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadFromThread32(ManagedRegister dest, ThreadOffset<4> src, size_t size) OVERRIDE; 6685a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers 669e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE; 67045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 671e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void LoadRef(ManagedRegister dest, ManagedRegister base, MemberOffset offs, 6724d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain bool unpoison_reference) OVERRIDE; 67345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 674dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs) OVERRIDE; 675a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 676dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadRawPtrFromThread32(ManagedRegister dest, ThreadOffset<4> offs) OVERRIDE; 677a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 6782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // Copying routines 679dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Move(ManagedRegister dest, ManagedRegister src, size_t size) OVERRIDE; 680a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 681dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CopyRawPtrFromThread32(FrameOffset fr_offs, ThreadOffset<4> thr_offs, 682dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 683a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 684dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CopyRawPtrToThread32(ThreadOffset<4> thr_offs, FrameOffset fr_offs, ManagedRegister scratch) 685dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OVERRIDE; 686a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 687dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch) OVERRIDE; 688a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 689dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch, size_t size) OVERRIDE; 69045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 691dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister scratch, 692dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 693dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 694dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src, ManagedRegister scratch, 695dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 6965a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers 697dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister scratch, 698dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 699dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 700dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset, 701dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch, size_t size) OVERRIDE; 7025a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers 703dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset, 704dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch, size_t size) OVERRIDE; 705dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 706dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void MemoryBarrier(ManagedRegister) OVERRIDE; 707e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers 70858136caeec7cb677bb83c2eafd1f4bab5afd96c8jeffhao // Sign extension 709dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE; 71058136caeec7cb677bb83c2eafd1f4bab5afd96c8jeffhao 711cee4d0c1c2faacf0eae748a24cc7e455e067d977jeffhao // Zero extension 712dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE; 713cee4d0c1c2faacf0eae748a24cc7e455e067d977jeffhao 7142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 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; 717a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 7182cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Set up out_reg to hold a Object** into the handle scope, or to be null if the 7192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // 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; 7242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 7252cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Set up out_off to hold a Object** into the handle scope, or to be null if the 7262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // value is null and null_allowed. 7272cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier void CreateHandleScopeEntry(FrameOffset out_off, FrameOffset handlescope_offset, 7282cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ManagedRegister scratch, bool null_allowed) OVERRIDE; 7292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 730eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // src holds a handle scope entry (Object**) load this into dst 731eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier void LoadReferenceFromHandleScope(ManagedRegister dst, ManagedRegister src) OVERRIDE; 7322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 7332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // Heap::VerifyObject on src. In some cases (such as a reference to this) we 7342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // know that src may not be null. 735dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE; 736dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE; 7372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 7382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // Call to address held at [base+offset] 739dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Call(ManagedRegister base, Offset offset, ManagedRegister scratch) OVERRIDE; 740dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Call(FrameOffset base, Offset offset, ManagedRegister scratch) OVERRIDE; 741dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CallFromThread32(ThreadOffset<4> offset, ManagedRegister scratch) OVERRIDE; 742a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 7432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // Generate code to check if Thread::Current()->exception_ is non-null 7442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // and branch to a ExceptionSlowPath if it is. 745dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void ExceptionPoll(ManagedRegister scratch, size_t stack_adjust) OVERRIDE; 746a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 7474d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain // 7484d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain // Heap poisoning. 7494d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain // 7504d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain 7514d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain // Poison a heap reference contained in `reg`. 7524d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain void PoisonHeapReference(Register reg) { negl(reg); } 7534d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain // Unpoison a heap reference contained in `reg`. 7544d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain void UnpoisonHeapReference(Register reg) { negl(reg); } 7554d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain // Unpoison a heap reference contained in `reg` if heap poisoning is enabled. 7564d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain void MaybeUnpoisonHeapReference(Register reg) { 7574d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain if (kPoisonHeapReferences) { 7584d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain UnpoisonHeapReference(reg); 7594d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain } 7604d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain } 7614d02711ea578dbb789abb30cbaf12f9926e13d81Roland Levillain 7620616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add a double to the constant area, returning the offset into 7630616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // the constant area where the literal resides. 764805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AddDouble(double v) { return constant_area_.AddDouble(v); } 7650616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 7660616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add a float to the constant area, returning the offset into 7670616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // the constant area where the literal resides. 768805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AddFloat(float v) { return constant_area_.AddFloat(v); } 7690616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 7700616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add an int32_t to the constant area, returning the offset into 7710616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // the constant area where the literal resides. 772805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AddInt32(int32_t v) { 773805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell return constant_area_.AddInt32(v); 774805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell } 775805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 776805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell // Add an int32_t to the end of the constant area, returning the offset into 777805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell // the constant area where the literal resides. 778805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AppendInt32(int32_t v) { 779805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell return constant_area_.AppendInt32(v); 780805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell } 7810616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 7820616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add an int64_t to the constant area, returning the offset into 7830616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // the constant area where the literal resides. 784805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t AddInt64(int64_t v) { return constant_area_.AddInt64(v); } 7850616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 7860616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Add the contents of the constant area to the assembler buffer. 7870616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell void AddConstantArea(); 7880616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 7890616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell // Is the constant area empty? Return true if there are no literals in the constant area. 7900616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell bool IsConstantAreaEmpty() const { return constant_area_.IsEmpty(); } 791805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell 792805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell // Return the current size of the constant area. 793805b3b56c6eb542298db33e0181f135dc9fed3d9Mark Mendell size_t ConstantAreaSize() const { return constant_area_.GetSize(); } 7940616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 795a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro private: 796a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro inline void EmitUint8(uint8_t value); 797a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro inline void EmitInt32(int32_t value); 798a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro inline void EmitRegisterOperand(int rm, int reg); 799a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); 800a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro inline void EmitFixup(AssemblerFixup* fixup); 801a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro inline void EmitOperandSizeOverride(); 802a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 803a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void EmitOperand(int rm, const Operand& operand); 804a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void EmitImmediate(const Immediate& imm); 805a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); 806a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void EmitLabel(Label* label, int instruction_size); 807a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro void EmitLabelLink(Label* label); 80873f455ecb76d063846a82735eb80596ceee8cee3Mark Mendell void EmitLabelLink(NearLabel* label); 809a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8107394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void EmitGenericShift(int rm, const Operand& operand, const Immediate& imm); 8117394569c9252b277710b2d7d3fc35fb0dd48fc4bMark P Mendell void EmitGenericShift(int rm, const Operand& operand, Register shifter); 812a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8130616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell ConstantArea constant_area_; 8140616ae081e648f4b9b64b33e2624a943c5fce977Mark Mendell 8152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers DISALLOW_COPY_AND_ASSIGN(X86Assembler); 816a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}; 817a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline void X86Assembler::EmitUint8(uint8_t value) { 819a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro buffer_.Emit<uint8_t>(value); 820a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro} 821a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline void X86Assembler::EmitInt32(int32_t value) { 823a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro buffer_.Emit<int32_t>(value); 824a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro} 825a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline void X86Assembler::EmitRegisterOperand(int rm, int reg) { 827a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro CHECK_GE(rm, 0); 828a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro CHECK_LT(rm, 8); 829a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg); 830a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro} 831a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline void X86Assembler::EmitXmmRegisterOperand(int rm, XmmRegister reg) { 833a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro EmitRegisterOperand(rm, static_cast<Register>(reg)); 834a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro} 835a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline void X86Assembler::EmitFixup(AssemblerFixup* fixup) { 837a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro buffer_.EmitFixup(fixup); 838a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro} 839a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline void X86Assembler::EmitOperandSizeOverride() { 841a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro EmitUint8(0x66); 842a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro} 843a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 8442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers// Slowpath entered when Thread::Current()->_exception is non-null 845dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass X86ExceptionSlowPath FINAL : public SlowPath { 8462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers public: 84793ba893c20532990a430741e0a97212900094e8cBrian Carlstrom explicit X86ExceptionSlowPath(size_t stack_adjust) : stack_adjust_(stack_adjust) {} 848dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers virtual void Emit(Assembler *sp_asm) OVERRIDE; 84900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private: 85000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const size_t stack_adjust_; 8512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}; 8522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 8532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} // namespace x86 8546b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro} // namespace art 855a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 856166db04e259ca51838c311891598664deeed85adIan Rogers#endif // ART_COMPILER_UTILS_X86_ASSEMBLER_X86_H_ 857