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