assembler_x86.h revision a04d397b990ee7d3ce120e317c19fb4409d80d57
1a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro// Copyright 2011 Google Inc. All Rights Reserved.
2a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
3a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro#ifndef ART_SRC_ASSEMBLER_X86_H_
4a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro#define ART_SRC_ASSEMBLER_X86_H_
5a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
60d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers#include <vector>
7578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "assembler.h"
8578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "constants.h"
9578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h"
10578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "managed_register.h"
11578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h"
12578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h"
13578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "utils.h"
14a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
156b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art {
16a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
17a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroclass Immediate {
18a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro public:
19a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  explicit Immediate(int32_t value) : value_(value) {}
20a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
21a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  int32_t value() const { return value_; }
22a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
23a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  bool is_int8() const { return IsInt(8, value_); }
24a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  bool is_uint8() const { return IsUint(8, value_); }
25a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  bool is_uint16() const { return IsUint(16, value_); }
26a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
27a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro private:
28a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  const int32_t value_;
29a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
30a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Immediate);
31a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro};
32a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
33a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
34a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroclass Operand {
35a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro public:
36a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  uint8_t mod() const {
37a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return (encoding_at(0) >> 6) & 3;
38a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
39a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
40a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Register rm() const {
41a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return static_cast<Register>(encoding_at(0) & 7);
42a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
43a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
44a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  ScaleFactor scale() const {
45a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
46a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
47a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
48a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Register index() const {
49a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return static_cast<Register>((encoding_at(1) >> 3) & 7);
50a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
51a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
52a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Register base() const {
53a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return static_cast<Register>(encoding_at(1) & 7);
54a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
55a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
56a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  int8_t disp8() const {
57a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_GE(length_, 2);
58a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return static_cast<int8_t>(encoding_[length_ - 1]);
59a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
60a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
61a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  int32_t disp32() const {
62a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_GE(length_, 5);
63a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    int32_t value;
64a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    memcpy(&value, &encoding_[length_ - 4], sizeof(value));
65a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return value;
66a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
67a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
68a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  bool IsRegister(Register reg) const {
69a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return ((encoding_[0] & 0xF8) == 0xC0)  // Addressing mode is register only.
70a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro        && ((encoding_[0] & 0x07) == reg);  // Register codes match.
71a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
72a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
73a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro protected:
74a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  // Operand can be sub classed (e.g: Address).
75a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Operand() : length_(0) { }
76a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
77a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void SetModRM(int mod, Register rm) {
78a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_EQ(mod & ~3, 0);
79a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    encoding_[0] = (mod << 6) | rm;
80a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    length_ = 1;
81a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
82a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
83a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void SetSIB(ScaleFactor scale, Register index, Register base) {
84a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_EQ(length_, 1);
85a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_EQ(scale & ~3, 0);
86a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    encoding_[1] = (scale << 6) | (index << 3) | base;
87a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    length_ = 2;
88a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
89a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
90a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void SetDisp8(int8_t disp) {
91a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK(length_ == 1 || length_ == 2);
92a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    encoding_[length_++] = static_cast<uint8_t>(disp);
93a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
94a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
95a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void SetDisp32(int32_t disp) {
96a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK(length_ == 1 || length_ == 2);
97a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    int disp_size = sizeof(disp);
98a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    memmove(&encoding_[length_], &disp, disp_size);
99a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    length_ += disp_size;
100a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
101a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
102a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro private:
103a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  byte length_;
104a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  byte encoding_[6];
105a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  byte padding_;
106a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
107a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  explicit Operand(Register reg) { SetModRM(3, reg); }
108a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
109a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  // Get the operand encoding byte at the given index.
110a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  uint8_t encoding_at(int index) const {
111a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_GE(index, 0);
112a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_LT(index, length_);
113a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return encoding_[index];
114a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
115a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
116a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  friend class Assembler;
117a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
118a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Operand);
119a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro};
120a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
121a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
122a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroclass Address : public Operand {
123a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro public:
124a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Address(Register base, int32_t disp) {
125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    Init(base, disp);
126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
128a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers  Address(Register base, Offset disp) {
129a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers    Init(base, disp.Int32Value());
130a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers  }
131a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers
132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Address(Register base, FrameOffset disp) {
133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(base, ESP);
134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    Init(ESP, disp.Int32Value());
135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Address(Register base, MemberOffset disp) {
138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    Init(base, disp.Int32Value());
139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void Init(Register base, int32_t disp) {
142a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    if (disp == 0 && base != EBP) {
143a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetModRM(0, base);
144a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      if (base == ESP) SetSIB(TIMES_1, ESP, base);
145a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    } else if (disp >= -128 && disp <= 127) {
146a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetModRM(1, base);
147a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      if (base == ESP) SetSIB(TIMES_1, ESP, base);
148a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetDisp8(disp);
149a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    } else {
150a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetModRM(2, base);
151a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      if (base == ESP) SetSIB(TIMES_1, ESP, base);
152a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetDisp32(disp);
153a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    }
154a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
155a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
157a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Address(Register index, ScaleFactor scale, int32_t disp) {
158a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_NE(index, ESP);  // Illegal addressing mode.
159a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    SetModRM(0, ESP);
160a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    SetSIB(scale, index, EBP);
161a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    SetDisp32(disp);
162a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
163a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
164a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
165a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    CHECK_NE(index, ESP);  // Illegal addressing mode.
166a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    if (disp == 0 && base != EBP) {
167a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetModRM(0, ESP);
168a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetSIB(scale, index, base);
169a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    } else if (disp >= -128 && disp <= 127) {
170a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetModRM(1, ESP);
171a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetSIB(scale, index, base);
172a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetDisp8(disp);
173a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    } else {
174a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetModRM(2, ESP);
175a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetSIB(scale, index, base);
176a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro      SetDisp32(disp);
177a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    }
178a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
179a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
18069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  static Address Absolute(uword addr) {
181a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    Address result;
182a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    result.SetModRM(0, EBP);
183a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    result.SetDisp32(addr);
184a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    return result;
185a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
186a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  static Address Absolute(ThreadOffset addr) {
188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return Absolute(addr.Int32Value());
189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
191a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro private:
192a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Address() {}
193a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
194a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Address);
195a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro};
196a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
197a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
198a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroclass Assembler {
199a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro public:
200a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  Assembler() : buffer_() {}
201a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  ~Assembler() {}
202a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
203a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  /*
204a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro   * Emit Machine Instructions.
205a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro   */
206a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void call(Register reg);
207a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void call(const Address& address);
208a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void call(Label* label);
209a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
210a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void pushl(Register reg);
211a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void pushl(const Address& address);
212a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void pushl(const Immediate& imm);
213a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
214a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void popl(Register reg);
215a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void popl(const Address& address);
216a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
217a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movl(Register dst, const Immediate& src);
218a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movl(Register dst, Register src);
219a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
220a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movl(Register dst, const Address& src);
221a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movl(const Address& dst, Register src);
222a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movl(const Address& dst, const Immediate& imm);
223a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
224a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movzxb(Register dst, ByteRegister src);
225a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movzxb(Register dst, const Address& src);
226a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movsxb(Register dst, ByteRegister src);
227a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movsxb(Register dst, const Address& src);
228a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movb(Register dst, const Address& src);
229a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movb(const Address& dst, ByteRegister src);
230a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movb(const Address& dst, const Immediate& imm);
231a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
232a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movzxw(Register dst, Register src);
233a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movzxw(Register dst, const Address& src);
234a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movsxw(Register dst, Register src);
235a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movsxw(Register dst, const Address& src);
236a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movw(Register dst, const Address& src);
237a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movw(const Address& dst, Register src);
238a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
239a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void leal(Register dst, const Address& src);
240a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void cmovl(Condition condition, Register dst, Register src);
242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void setb(Condition condition, Register dst);
244a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
245a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movss(XmmRegister dst, const Address& src);
246a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movss(const Address& dst, XmmRegister src);
247a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movss(XmmRegister dst, XmmRegister src);
248a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
249a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movd(XmmRegister dst, Register src);
250a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movd(Register dst, XmmRegister src);
251a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
252a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addss(XmmRegister dst, XmmRegister src);
253a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addss(XmmRegister dst, const Address& src);
254a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void subss(XmmRegister dst, XmmRegister src);
255a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void subss(XmmRegister dst, const Address& src);
256a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void mulss(XmmRegister dst, XmmRegister src);
257a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void mulss(XmmRegister dst, const Address& src);
258a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void divss(XmmRegister dst, XmmRegister src);
259a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void divss(XmmRegister dst, const Address& src);
260a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
261a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movsd(XmmRegister dst, const Address& src);
262a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movsd(const Address& dst, XmmRegister src);
263a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void movsd(XmmRegister dst, XmmRegister src);
264a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
265a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addsd(XmmRegister dst, XmmRegister src);
266a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addsd(XmmRegister dst, const Address& src);
267a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void subsd(XmmRegister dst, XmmRegister src);
268a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void subsd(XmmRegister dst, const Address& src);
269a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void mulsd(XmmRegister dst, XmmRegister src);
270a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void mulsd(XmmRegister dst, const Address& src);
271a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void divsd(XmmRegister dst, XmmRegister src);
272a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void divsd(XmmRegister dst, const Address& src);
273a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
274a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvtsi2ss(XmmRegister dst, Register src);
275a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvtsi2sd(XmmRegister dst, Register src);
276a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
277a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvtss2si(Register dst, XmmRegister src);
278a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvtss2sd(XmmRegister dst, XmmRegister src);
279a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
280a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvtsd2si(Register dst, XmmRegister src);
281a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvtsd2ss(XmmRegister dst, XmmRegister src);
282a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
283a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvttss2si(Register dst, XmmRegister src);
284a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvttsd2si(Register dst, XmmRegister src);
285a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
286a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cvtdq2pd(XmmRegister dst, XmmRegister src);
287a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
288a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void comiss(XmmRegister a, XmmRegister b);
289a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void comisd(XmmRegister a, XmmRegister b);
290a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
291a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void sqrtsd(XmmRegister dst, XmmRegister src);
292a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void sqrtss(XmmRegister dst, XmmRegister src);
293a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
294a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void xorpd(XmmRegister dst, const Address& src);
295a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void xorpd(XmmRegister dst, XmmRegister src);
296a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void xorps(XmmRegister dst, const Address& src);
297a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void xorps(XmmRegister dst, XmmRegister src);
298a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
299a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void andpd(XmmRegister dst, const Address& src);
300a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
301a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void flds(const Address& src);
302a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fstps(const Address& dst);
303a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
304a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fldl(const Address& src);
305a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fstpl(const Address& dst);
306a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
307a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fnstcw(const Address& dst);
308a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fldcw(const Address& src);
309a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
310a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fistpl(const Address& dst);
311a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fistps(const Address& dst);
312a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fildl(const Address& src);
313a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
314a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fincstp();
315a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void ffree(const Immediate& index);
316a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
317a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fsin();
318a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fcos();
319a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void fptan();
320a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
321a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void xchgl(Register dst, Register src);
322a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
323a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cmpl(Register reg, const Immediate& imm);
324a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cmpl(Register reg0, Register reg1);
325a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cmpl(Register reg, const Address& address);
326a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
327a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cmpl(const Address& address, Register reg);
328a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cmpl(const Address& address, const Immediate& imm);
329a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
330a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void testl(Register reg1, Register reg2);
331a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void testl(Register reg, const Immediate& imm);
332a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
333a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void andl(Register dst, const Immediate& imm);
334a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void andl(Register dst, Register src);
335a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
336a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void orl(Register dst, const Immediate& imm);
337a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void orl(Register dst, Register src);
338a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
339a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void xorl(Register dst, Register src);
340a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
341a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addl(Register dst, Register src);
342a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addl(Register reg, const Immediate& imm);
343a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addl(Register reg, const Address& address);
344a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
345a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addl(const Address& address, Register reg);
346a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void addl(const Address& address, const Immediate& imm);
347a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
348a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void adcl(Register dst, Register src);
349a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void adcl(Register reg, const Immediate& imm);
350a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void adcl(Register dst, const Address& address);
351a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
352a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void subl(Register dst, Register src);
353a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void subl(Register reg, const Immediate& imm);
354a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void subl(Register reg, const Address& address);
355a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
356a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cdq();
357a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
358a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void idivl(Register reg);
359a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
360a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void imull(Register dst, Register src);
361a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void imull(Register reg, const Immediate& imm);
362a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void imull(Register reg, const Address& address);
363a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
364a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void imull(Register reg);
365a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void imull(const Address& address);
366a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
367a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void mull(Register reg);
368a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void mull(const Address& address);
369a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
370a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void sbbl(Register dst, Register src);
371a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void sbbl(Register reg, const Immediate& imm);
372a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void sbbl(Register reg, const Address& address);
373a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
374a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void incl(Register reg);
375a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void incl(const Address& address);
376a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
377a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void decl(Register reg);
378a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void decl(const Address& address);
379a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
380a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void shll(Register reg, const Immediate& imm);
381a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void shll(Register operand, Register shifter);
382a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void shrl(Register reg, const Immediate& imm);
383a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void shrl(Register operand, Register shifter);
384a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void sarl(Register reg, const Immediate& imm);
385a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void sarl(Register operand, Register shifter);
386a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void shld(Register dst, Register src);
387a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
388a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void negl(Register reg);
389a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void notl(Register reg);
390a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
391a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void enter(const Immediate& imm);
392a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void leave();
393a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
394a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void ret();
395a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void ret(const Immediate& imm);
396a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
397a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void nop();
398a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void int3();
399a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void hlt();
400a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
401a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void j(Condition condition, Label* label);
402a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
403a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void jmp(Register reg);
404a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void jmp(Label* label);
405a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
4060d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  Assembler* lock();
407a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void cmpxchgl(const Address& address, Register reg);
408a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
4090d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  Assembler* fs();
410b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
411b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  //
412b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Macros for High-level operations.
413b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  //
414b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
415b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Emit code that will create an activation on the stack
4160d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  void BuildFrame(size_t frame_size, ManagedRegister method_reg,
4170d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers                  const std::vector<ManagedRegister>& spill_regs);
418b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
419b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Emit code that will remove an activation from the stack
4200d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  void RemoveFrame(size_t frame_size,
4210d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers                   const std::vector<ManagedRegister>& spill_regs);
4220d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers
4230d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  // Fill registers from spill area - no-op on x86
4240d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  void FillFromSpillArea(const std::vector<ManagedRegister>& spill_regs,
4250d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers                         size_t displacement);
426b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
427b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void IncreaseFrameSize(size_t adjust);
428b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void DecreaseFrameSize(size_t adjust);
429b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
430b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Store bytes from the given register onto the stack
431b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void Store(FrameOffset offs, ManagedRegister src, size_t size);
432b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void StoreRef(FrameOffset dest, ManagedRegister src);
433df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers  void StoreRawPtr(FrameOffset dest, ManagedRegister src);
434b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
435b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch);
436b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
437b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
438b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                             ManagedRegister scratch);
439b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
440b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
441b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                              ManagedRegister scratch);
442b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
443b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void Load(ManagedRegister dest, FrameOffset src, size_t size);
444b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
445b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void LoadRef(ManagedRegister dest, FrameOffset  src);
446b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
447b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void LoadRef(ManagedRegister dest, ManagedRegister base, MemberOffset offs);
448b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
449a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers  void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs);
450a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers
451b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset offs);
452b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
453b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset thr_offs,
454b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                            ManagedRegister scratch);
455b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
456b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void CopyRawPtrToThread(ThreadOffset thr_offs, FrameOffset fr_offs,
457b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                          ManagedRegister scratch);
458b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
459b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void StoreStackOffsetToThread(ThreadOffset thr_offs, FrameOffset fr_offs,
460b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                ManagedRegister scratch);
46145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  void StoreStackPointerToThread(ThreadOffset thr_offs);
46245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
463b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void Move(ManagedRegister dest, ManagedRegister src);
464b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
465b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch,
466b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers            unsigned int size);
467b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
468b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void CreateStackHandle(ManagedRegister out_reg, FrameOffset handle_offset,
469b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                         ManagedRegister in_reg, bool null_allowed);
470b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
471b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void CreateStackHandle(FrameOffset out_off, FrameOffset handle_offset,
472b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                         ManagedRegister scratch, bool null_allowed);
473b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
474df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers  void LoadReferenceFromStackHandle(ManagedRegister dst, ManagedRegister src);
475b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
476b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void ValidateRef(ManagedRegister src, bool could_be_null);
477b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void ValidateRef(FrameOffset src, bool could_be_null);
478b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
479df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers  void Call(ManagedRegister base, Offset offset, ManagedRegister scratch);
480e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  void Call(FrameOffset base, Offset offset, ManagedRegister scratch);
481b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
48245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // Generate code to check if Thread::Current()->suspend_count_ is non-zero
48345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // and branch to a SuspendSlowPath if it is. The SuspendSlowPath will continue
48445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // at the next instruction.
48545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  void SuspendPoll(ManagedRegister scratch, ManagedRegister return_reg,
48645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers                   FrameOffset return_save_location, size_t return_size);
48745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
48845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // Generate code to check if Thread::Current()->exception_ is non-null
48945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // and branch to a ExceptionSlowPath if it is.
49045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  void ExceptionPoll(ManagedRegister scratch);
49145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
492a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void AddImmediate(Register reg, const Immediate& imm);
493a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
494a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void LoadDoubleConstant(XmmRegister dst, double value);
495a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
496a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void DoubleNegate(XmmRegister d);
497a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void FloatNegate(XmmRegister f);
498a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
499a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void DoubleAbs(XmmRegister reg);
500a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
501a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void LockCmpxchgl(const Address& address, Register reg) {
5020d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers    lock()->cmpxchgl(address, reg);
503a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
504a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
505b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  //
506b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Misc. functionality
507b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  //
508a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  int PreferredLoopAlignment() { return 16; }
509a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void Align(int alignment, int offset);
510a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void Bind(Label* label);
511a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
51245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  void EmitSlowPaths() { buffer_.EmitSlowPaths(this); }
51345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
514b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  size_t CodeSize() const { return buffer_.Size(); }
515a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
516a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void FinalizeInstructions(const MemoryRegion& region) {
517a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro    buffer_.FinalizeInstructions(region);
518a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  }
519a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
520a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  // Debugging and bringup support.
521a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void Stop(const char* message);
522a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
523a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  static void InitializeMemoryWithBreakpoints(byte* data, size_t length);
524a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
525a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro private:
526a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  AssemblerBuffer buffer_;
527a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
528a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  inline void EmitUint8(uint8_t value);
529a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  inline void EmitInt32(int32_t value);
530a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  inline void EmitRegisterOperand(int rm, int reg);
531a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  inline void EmitXmmRegisterOperand(int rm, XmmRegister reg);
532a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  inline void EmitFixup(AssemblerFixup* fixup);
533a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  inline void EmitOperandSizeOverride();
534a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
535a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void EmitOperand(int rm, const Operand& operand);
536a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void EmitImmediate(const Immediate& imm);
537a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void EmitComplex(int rm, const Operand& operand, const Immediate& immediate);
538a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void EmitLabel(Label* label, int instruction_size);
539a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void EmitLabelLink(Label* label);
540a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void EmitNearLabelLink(Label* label);
541a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
542a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void EmitGenericShift(int rm, Register reg, const Immediate& imm);
543a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  void EmitGenericShift(int rm, Register operand, Register shifter);
544a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
545a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Assembler);
546a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro};
547a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
548a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
549a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroinline void Assembler::EmitUint8(uint8_t value) {
550a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  buffer_.Emit<uint8_t>(value);
551a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}
552a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
553a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
554a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroinline void Assembler::EmitInt32(int32_t value) {
555a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  buffer_.Emit<int32_t>(value);
556a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}
557a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
558a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
559a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroinline void Assembler::EmitRegisterOperand(int rm, int reg) {
560a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  CHECK_GE(rm, 0);
561a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  CHECK_LT(rm, 8);
562a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg);
563a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}
564a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
565a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
566a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroinline void Assembler::EmitXmmRegisterOperand(int rm, XmmRegister reg) {
567a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  EmitRegisterOperand(rm, static_cast<Register>(reg));
568a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}
569a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
570a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
571a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroinline void Assembler::EmitFixup(AssemblerFixup* fixup) {
572a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  buffer_.EmitFixup(fixup);
573a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}
574a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
575a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
576a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiroinline void Assembler::EmitOperandSizeOverride() {
577a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro  EmitUint8(0x66);
578a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro}
579a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
5806b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro}  // namespace art
581a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
582a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro#endif  // ART_SRC_ASSEMBLER_X86_H_
583