xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceAssemblerX8632.h (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceAssemblerX8632.h - Assembler for x86-32 ---*- C++ -*-===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
4*03ce13f7SAndroid Build Coastguard Worker // for details. All rights reserved. Use of this source code is governed by a
5*03ce13f7SAndroid Build Coastguard Worker // BSD-style license that can be found in the LICENSE file.
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker // Modified by the Subzero authors.
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
10*03ce13f7SAndroid Build Coastguard Worker //
11*03ce13f7SAndroid Build Coastguard Worker //                        The Subzero Code Generator
12*03ce13f7SAndroid Build Coastguard Worker //
13*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
14*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
15*03ce13f7SAndroid Build Coastguard Worker //
16*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
17*03ce13f7SAndroid Build Coastguard Worker ///
18*03ce13f7SAndroid Build Coastguard Worker /// \file
19*03ce13f7SAndroid Build Coastguard Worker /// \brief Declares the Assembler class for X86-32.
20*03ce13f7SAndroid Build Coastguard Worker ///
21*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
22*03ce13f7SAndroid Build Coastguard Worker 
23*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICEASSEMBLERX8632_H
24*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICEASSEMBLERX8632_H
25*03ce13f7SAndroid Build Coastguard Worker 
26*03ce13f7SAndroid Build Coastguard Worker #include "IceAssembler.h"
27*03ce13f7SAndroid Build Coastguard Worker #include "IceConditionCodesX86.h"
28*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h"
29*03ce13f7SAndroid Build Coastguard Worker #include "IceOperand.h"
30*03ce13f7SAndroid Build Coastguard Worker #include "IceRegistersX8632.h"
31*03ce13f7SAndroid Build Coastguard Worker #include "IceTypes.h"
32*03ce13f7SAndroid Build Coastguard Worker #include "IceUtils.h"
33*03ce13f7SAndroid Build Coastguard Worker 
34*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
35*03ce13f7SAndroid Build Coastguard Worker namespace X8632 {
36*03ce13f7SAndroid Build Coastguard Worker 
37*03ce13f7SAndroid Build Coastguard Worker using BrCond = CondX86::BrCond;
38*03ce13f7SAndroid Build Coastguard Worker using CmppsCond = CondX86::CmppsCond;
39*03ce13f7SAndroid Build Coastguard Worker using RegisterSet = ::Ice::RegX8632;
40*03ce13f7SAndroid Build Coastguard Worker using GPRRegister = RegisterSet::GPRRegister;
41*03ce13f7SAndroid Build Coastguard Worker using ByteRegister = RegisterSet::ByteRegister;
42*03ce13f7SAndroid Build Coastguard Worker using XmmRegister = RegisterSet::XmmRegister;
43*03ce13f7SAndroid Build Coastguard Worker 
44*03ce13f7SAndroid Build Coastguard Worker class X86OperandMem;
45*03ce13f7SAndroid Build Coastguard Worker class VariableSplit;
46*03ce13f7SAndroid Build Coastguard Worker class TargetX8632;
47*03ce13f7SAndroid Build Coastguard Worker 
48*03ce13f7SAndroid Build Coastguard Worker constexpr FixupKind FK_PcRel = llvm::ELF::R_386_PC32;
49*03ce13f7SAndroid Build Coastguard Worker constexpr FixupKind FK_Abs = llvm::ELF::R_386_32;
50*03ce13f7SAndroid Build Coastguard Worker constexpr FixupKind FK_Gotoff = llvm::ELF::R_386_GOTOFF;
51*03ce13f7SAndroid Build Coastguard Worker constexpr FixupKind FK_GotPC = llvm::ELF::R_386_GOTPC;
52*03ce13f7SAndroid Build Coastguard Worker 
53*03ce13f7SAndroid Build Coastguard Worker enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
54*03ce13f7SAndroid Build Coastguard Worker 
55*03ce13f7SAndroid Build Coastguard Worker class AsmOperand {
56*03ce13f7SAndroid Build Coastguard Worker public:
AsmOperand(const AsmOperand & other)57*03ce13f7SAndroid Build Coastguard Worker   AsmOperand(const AsmOperand &other)
58*03ce13f7SAndroid Build Coastguard Worker       : fixup_(other.fixup_), length_(other.length_) {
59*03ce13f7SAndroid Build Coastguard Worker     memmove(&encoding_[0], &other.encoding_[0], other.length_);
60*03ce13f7SAndroid Build Coastguard Worker   }
61*03ce13f7SAndroid Build Coastguard Worker 
62*03ce13f7SAndroid Build Coastguard Worker   AsmOperand &operator=(const AsmOperand &other) {
63*03ce13f7SAndroid Build Coastguard Worker     length_ = other.length_;
64*03ce13f7SAndroid Build Coastguard Worker     fixup_ = other.fixup_;
65*03ce13f7SAndroid Build Coastguard Worker     memmove(&encoding_[0], &other.encoding_[0], other.length_);
66*03ce13f7SAndroid Build Coastguard Worker     return *this;
67*03ce13f7SAndroid Build Coastguard Worker   }
68*03ce13f7SAndroid Build Coastguard Worker 
mod()69*03ce13f7SAndroid Build Coastguard Worker   uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
70*03ce13f7SAndroid Build Coastguard Worker 
rm()71*03ce13f7SAndroid Build Coastguard Worker   GPRRegister rm() const {
72*03ce13f7SAndroid Build Coastguard Worker     return static_cast<GPRRegister>(encoding_at(0) & 7);
73*03ce13f7SAndroid Build Coastguard Worker   }
74*03ce13f7SAndroid Build Coastguard Worker 
scale()75*03ce13f7SAndroid Build Coastguard Worker   ScaleFactor scale() const {
76*03ce13f7SAndroid Build Coastguard Worker     return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
77*03ce13f7SAndroid Build Coastguard Worker   }
78*03ce13f7SAndroid Build Coastguard Worker 
index()79*03ce13f7SAndroid Build Coastguard Worker   GPRRegister index() const {
80*03ce13f7SAndroid Build Coastguard Worker     return static_cast<GPRRegister>((encoding_at(1) >> 3) & 7);
81*03ce13f7SAndroid Build Coastguard Worker   }
82*03ce13f7SAndroid Build Coastguard Worker 
base()83*03ce13f7SAndroid Build Coastguard Worker   GPRRegister base() const {
84*03ce13f7SAndroid Build Coastguard Worker     return static_cast<GPRRegister>(encoding_at(1) & 7);
85*03ce13f7SAndroid Build Coastguard Worker   }
86*03ce13f7SAndroid Build Coastguard Worker 
disp8()87*03ce13f7SAndroid Build Coastguard Worker   int8_t disp8() const {
88*03ce13f7SAndroid Build Coastguard Worker     assert(length_ >= 2);
89*03ce13f7SAndroid Build Coastguard Worker     return static_cast<int8_t>(encoding_[length_ - 1]);
90*03ce13f7SAndroid Build Coastguard Worker   }
91*03ce13f7SAndroid Build Coastguard Worker 
fixup()92*03ce13f7SAndroid Build Coastguard Worker   AssemblerFixup *fixup() const { return fixup_; }
93*03ce13f7SAndroid Build Coastguard Worker 
94*03ce13f7SAndroid Build Coastguard Worker protected:
AsmOperand()95*03ce13f7SAndroid Build Coastguard Worker   AsmOperand()
96*03ce13f7SAndroid Build Coastguard Worker       : fixup_(nullptr), length_(0) {} // Needed by subclass AsmAddress.
97*03ce13f7SAndroid Build Coastguard Worker 
SetModRM(int mod,GPRRegister rm)98*03ce13f7SAndroid Build Coastguard Worker   void SetModRM(int mod, GPRRegister rm) {
99*03ce13f7SAndroid Build Coastguard Worker     assert((mod & ~3) == 0);
100*03ce13f7SAndroid Build Coastguard Worker     encoding_[0] = (mod << 6) | rm;
101*03ce13f7SAndroid Build Coastguard Worker     length_ = 1;
102*03ce13f7SAndroid Build Coastguard Worker   }
103*03ce13f7SAndroid Build Coastguard Worker 
SetSIB(ScaleFactor scale,GPRRegister index,GPRRegister base)104*03ce13f7SAndroid Build Coastguard Worker   void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
105*03ce13f7SAndroid Build Coastguard Worker     assert(length_ == 1);
106*03ce13f7SAndroid Build Coastguard Worker     assert((scale & ~3) == 0);
107*03ce13f7SAndroid Build Coastguard Worker     encoding_[1] = (scale << 6) | (index << 3) | base;
108*03ce13f7SAndroid Build Coastguard Worker     length_ = 2;
109*03ce13f7SAndroid Build Coastguard Worker   }
110*03ce13f7SAndroid Build Coastguard Worker 
SetDisp8(int8_t disp)111*03ce13f7SAndroid Build Coastguard Worker   void SetDisp8(int8_t disp) {
112*03ce13f7SAndroid Build Coastguard Worker     assert(length_ == 1 || length_ == 2);
113*03ce13f7SAndroid Build Coastguard Worker     encoding_[length_++] = static_cast<uint8_t>(disp);
114*03ce13f7SAndroid Build Coastguard Worker   }
115*03ce13f7SAndroid Build Coastguard Worker 
SetDisp32(int32_t disp)116*03ce13f7SAndroid Build Coastguard Worker   void SetDisp32(int32_t disp) {
117*03ce13f7SAndroid Build Coastguard Worker     assert(length_ == 1 || length_ == 2);
118*03ce13f7SAndroid Build Coastguard Worker     intptr_t disp_size = sizeof(disp);
119*03ce13f7SAndroid Build Coastguard Worker     memmove(&encoding_[length_], &disp, disp_size);
120*03ce13f7SAndroid Build Coastguard Worker     length_ += disp_size;
121*03ce13f7SAndroid Build Coastguard Worker   }
122*03ce13f7SAndroid Build Coastguard Worker 
SetFixup(AssemblerFixup * fixup)123*03ce13f7SAndroid Build Coastguard Worker   void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
124*03ce13f7SAndroid Build Coastguard Worker 
125*03ce13f7SAndroid Build Coastguard Worker private:
126*03ce13f7SAndroid Build Coastguard Worker   AssemblerFixup *fixup_;
127*03ce13f7SAndroid Build Coastguard Worker   uint8_t encoding_[6];
128*03ce13f7SAndroid Build Coastguard Worker   uint8_t length_;
129*03ce13f7SAndroid Build Coastguard Worker 
AsmOperand(GPRRegister reg)130*03ce13f7SAndroid Build Coastguard Worker   explicit AsmOperand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
131*03ce13f7SAndroid Build Coastguard Worker 
132*03ce13f7SAndroid Build Coastguard Worker   /// Get the operand encoding byte at the given index.
encoding_at(intptr_t index)133*03ce13f7SAndroid Build Coastguard Worker   uint8_t encoding_at(intptr_t index) const {
134*03ce13f7SAndroid Build Coastguard Worker     assert(index >= 0 && index < length_);
135*03ce13f7SAndroid Build Coastguard Worker     return encoding_[index];
136*03ce13f7SAndroid Build Coastguard Worker   }
137*03ce13f7SAndroid Build Coastguard Worker 
138*03ce13f7SAndroid Build Coastguard Worker   /// Returns whether or not this operand is really the given register in
139*03ce13f7SAndroid Build Coastguard Worker   /// disguise. Used from the assembler to generate better encodings.
IsRegister(GPRRegister reg)140*03ce13f7SAndroid Build Coastguard Worker   bool IsRegister(GPRRegister reg) const {
141*03ce13f7SAndroid Build Coastguard Worker     return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
142*03ce13f7SAndroid Build Coastguard Worker            && ((encoding_[0] & 0x07) == reg); // Register codes match.
143*03ce13f7SAndroid Build Coastguard Worker   }
144*03ce13f7SAndroid Build Coastguard Worker 
145*03ce13f7SAndroid Build Coastguard Worker   friend class AssemblerX8632;
146*03ce13f7SAndroid Build Coastguard Worker };
147*03ce13f7SAndroid Build Coastguard Worker 
148*03ce13f7SAndroid Build Coastguard Worker class AsmAddress : public AsmOperand {
149*03ce13f7SAndroid Build Coastguard Worker   AsmAddress() = delete;
150*03ce13f7SAndroid Build Coastguard Worker 
151*03ce13f7SAndroid Build Coastguard Worker public:
152*03ce13f7SAndroid Build Coastguard Worker   AsmAddress(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup = nullptr) {
153*03ce13f7SAndroid Build Coastguard Worker     SetBase(Base, Disp, Fixup);
154*03ce13f7SAndroid Build Coastguard Worker   }
155*03ce13f7SAndroid Build Coastguard Worker   AsmAddress(const Variable *Var, const TargetX8632 *Target);
156*03ce13f7SAndroid Build Coastguard Worker   AsmAddress(const X86OperandMem *Mem, Ice::Assembler *Asm,
157*03ce13f7SAndroid Build Coastguard Worker              const Ice::TargetLowering *Target);
158*03ce13f7SAndroid Build Coastguard Worker   AsmAddress(const VariableSplit *Split, const Cfg *Func);
159*03ce13f7SAndroid Build Coastguard Worker 
160*03ce13f7SAndroid Build Coastguard Worker   // Address into the constant pool.
AsmAddress(const Constant * Imm,Ice::Assembler * Asm)161*03ce13f7SAndroid Build Coastguard Worker   AsmAddress(const Constant *Imm, Ice::Assembler *Asm) {
162*03ce13f7SAndroid Build Coastguard Worker     AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
163*03ce13f7SAndroid Build Coastguard Worker     const RelocOffsetT Offset = 0;
164*03ce13f7SAndroid Build Coastguard Worker     SetAbsolute(Offset, Fixup);
165*03ce13f7SAndroid Build Coastguard Worker   }
166*03ce13f7SAndroid Build Coastguard Worker 
167*03ce13f7SAndroid Build Coastguard Worker private:
AsmAddress(const AsmAddress & other)168*03ce13f7SAndroid Build Coastguard Worker   AsmAddress(const AsmAddress &other) : AsmOperand(other) {}
169*03ce13f7SAndroid Build Coastguard Worker 
170*03ce13f7SAndroid Build Coastguard Worker   AsmAddress &operator=(const AsmAddress &other) {
171*03ce13f7SAndroid Build Coastguard Worker     AsmOperand::operator=(other);
172*03ce13f7SAndroid Build Coastguard Worker     return *this;
173*03ce13f7SAndroid Build Coastguard Worker   }
174*03ce13f7SAndroid Build Coastguard Worker 
SetBase(GPRRegister Base,int32_t Disp,AssemblerFixup * Fixup)175*03ce13f7SAndroid Build Coastguard Worker   void SetBase(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup) {
176*03ce13f7SAndroid Build Coastguard Worker     if (Fixup == nullptr && Disp == 0 && Base != RegX8632::Encoded_Reg_ebp) {
177*03ce13f7SAndroid Build Coastguard Worker       SetModRM(0, Base);
178*03ce13f7SAndroid Build Coastguard Worker       if (Base == RegX8632::Encoded_Reg_esp)
179*03ce13f7SAndroid Build Coastguard Worker         SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
180*03ce13f7SAndroid Build Coastguard Worker     } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
181*03ce13f7SAndroid Build Coastguard Worker       SetModRM(1, Base);
182*03ce13f7SAndroid Build Coastguard Worker       if (Base == RegX8632::Encoded_Reg_esp)
183*03ce13f7SAndroid Build Coastguard Worker         SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
184*03ce13f7SAndroid Build Coastguard Worker       SetDisp8(Disp);
185*03ce13f7SAndroid Build Coastguard Worker     } else {
186*03ce13f7SAndroid Build Coastguard Worker       SetModRM(2, Base);
187*03ce13f7SAndroid Build Coastguard Worker       if (Base == RegX8632::Encoded_Reg_esp)
188*03ce13f7SAndroid Build Coastguard Worker         SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
189*03ce13f7SAndroid Build Coastguard Worker       SetDisp32(Disp);
190*03ce13f7SAndroid Build Coastguard Worker       if (Fixup)
191*03ce13f7SAndroid Build Coastguard Worker         SetFixup(Fixup);
192*03ce13f7SAndroid Build Coastguard Worker     }
193*03ce13f7SAndroid Build Coastguard Worker   }
194*03ce13f7SAndroid Build Coastguard Worker 
SetIndex(GPRRegister Index,ScaleFactor Scale,int32_t Disp,AssemblerFixup * Fixup)195*03ce13f7SAndroid Build Coastguard Worker   void SetIndex(GPRRegister Index, ScaleFactor Scale, int32_t Disp,
196*03ce13f7SAndroid Build Coastguard Worker                 AssemblerFixup *Fixup) {
197*03ce13f7SAndroid Build Coastguard Worker     assert(Index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
198*03ce13f7SAndroid Build Coastguard Worker     SetModRM(0, RegX8632::Encoded_Reg_esp);
199*03ce13f7SAndroid Build Coastguard Worker     SetSIB(Scale, Index, RegX8632::Encoded_Reg_ebp);
200*03ce13f7SAndroid Build Coastguard Worker     SetDisp32(Disp);
201*03ce13f7SAndroid Build Coastguard Worker     if (Fixup)
202*03ce13f7SAndroid Build Coastguard Worker       SetFixup(Fixup);
203*03ce13f7SAndroid Build Coastguard Worker   }
204*03ce13f7SAndroid Build Coastguard Worker 
SetBaseIndex(GPRRegister Base,GPRRegister Index,ScaleFactor Scale,int32_t Disp,AssemblerFixup * Fixup)205*03ce13f7SAndroid Build Coastguard Worker   void SetBaseIndex(GPRRegister Base, GPRRegister Index, ScaleFactor Scale,
206*03ce13f7SAndroid Build Coastguard Worker                     int32_t Disp, AssemblerFixup *Fixup) {
207*03ce13f7SAndroid Build Coastguard Worker     assert(Index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
208*03ce13f7SAndroid Build Coastguard Worker     if (Fixup == nullptr && Disp == 0 && Base != RegX8632::Encoded_Reg_ebp) {
209*03ce13f7SAndroid Build Coastguard Worker       SetModRM(0, RegX8632::Encoded_Reg_esp);
210*03ce13f7SAndroid Build Coastguard Worker       SetSIB(Scale, Index, Base);
211*03ce13f7SAndroid Build Coastguard Worker     } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
212*03ce13f7SAndroid Build Coastguard Worker       SetModRM(1, RegX8632::Encoded_Reg_esp);
213*03ce13f7SAndroid Build Coastguard Worker       SetSIB(Scale, Index, Base);
214*03ce13f7SAndroid Build Coastguard Worker       SetDisp8(Disp);
215*03ce13f7SAndroid Build Coastguard Worker     } else {
216*03ce13f7SAndroid Build Coastguard Worker       SetModRM(2, RegX8632::Encoded_Reg_esp);
217*03ce13f7SAndroid Build Coastguard Worker       SetSIB(Scale, Index, Base);
218*03ce13f7SAndroid Build Coastguard Worker       SetDisp32(Disp);
219*03ce13f7SAndroid Build Coastguard Worker       if (Fixup)
220*03ce13f7SAndroid Build Coastguard Worker         SetFixup(Fixup);
221*03ce13f7SAndroid Build Coastguard Worker     }
222*03ce13f7SAndroid Build Coastguard Worker   }
223*03ce13f7SAndroid Build Coastguard Worker 
224*03ce13f7SAndroid Build Coastguard Worker   /// Generate an absolute address expression on x86-32.
SetAbsolute(RelocOffsetT Offset,AssemblerFixup * Fixup)225*03ce13f7SAndroid Build Coastguard Worker   void SetAbsolute(RelocOffsetT Offset, AssemblerFixup *Fixup) {
226*03ce13f7SAndroid Build Coastguard Worker     SetModRM(0, RegX8632::Encoded_Reg_ebp);
227*03ce13f7SAndroid Build Coastguard Worker     // Use the Offset in the displacement for now. If we decide to process
228*03ce13f7SAndroid Build Coastguard Worker     // fixups later, we'll need to patch up the emitted displacement.
229*03ce13f7SAndroid Build Coastguard Worker     SetDisp32(Offset);
230*03ce13f7SAndroid Build Coastguard Worker     if (Fixup)
231*03ce13f7SAndroid Build Coastguard Worker       SetFixup(Fixup);
232*03ce13f7SAndroid Build Coastguard Worker   }
233*03ce13f7SAndroid Build Coastguard Worker };
234*03ce13f7SAndroid Build Coastguard Worker 
235*03ce13f7SAndroid Build Coastguard Worker class AssemblerX8632 : public ::Ice::Assembler {
236*03ce13f7SAndroid Build Coastguard Worker   AssemblerX8632(const AssemblerX8632 &) = delete;
237*03ce13f7SAndroid Build Coastguard Worker   AssemblerX8632 &operator=(const AssemblerX8632 &) = delete;
238*03ce13f7SAndroid Build Coastguard Worker 
239*03ce13f7SAndroid Build Coastguard Worker protected:
AssemblerX8632()240*03ce13f7SAndroid Build Coastguard Worker   explicit AssemblerX8632() : Assembler(Asm_X8632) {}
241*03ce13f7SAndroid Build Coastguard Worker 
242*03ce13f7SAndroid Build Coastguard Worker public:
243*03ce13f7SAndroid Build Coastguard Worker   static constexpr int MAX_NOP_SIZE = 8;
244*03ce13f7SAndroid Build Coastguard Worker 
classof(const Assembler * Asm)245*03ce13f7SAndroid Build Coastguard Worker   static bool classof(const Assembler *Asm) {
246*03ce13f7SAndroid Build Coastguard Worker     return Asm->getKind() == Asm_X8632;
247*03ce13f7SAndroid Build Coastguard Worker   }
248*03ce13f7SAndroid Build Coastguard Worker 
249*03ce13f7SAndroid Build Coastguard Worker   class Immediate {
250*03ce13f7SAndroid Build Coastguard Worker     Immediate(const Immediate &) = delete;
251*03ce13f7SAndroid Build Coastguard Worker     Immediate &operator=(const Immediate &) = delete;
252*03ce13f7SAndroid Build Coastguard Worker 
253*03ce13f7SAndroid Build Coastguard Worker   public:
Immediate(int32_t value)254*03ce13f7SAndroid Build Coastguard Worker     explicit Immediate(int32_t value) : value_(value) {}
255*03ce13f7SAndroid Build Coastguard Worker 
Immediate(AssemblerFixup * fixup)256*03ce13f7SAndroid Build Coastguard Worker     explicit Immediate(AssemblerFixup *fixup) : fixup_(fixup) {}
257*03ce13f7SAndroid Build Coastguard Worker 
value()258*03ce13f7SAndroid Build Coastguard Worker     int32_t value() const { return value_; }
fixup()259*03ce13f7SAndroid Build Coastguard Worker     AssemblerFixup *fixup() const { return fixup_; }
260*03ce13f7SAndroid Build Coastguard Worker 
is_int8()261*03ce13f7SAndroid Build Coastguard Worker     bool is_int8() const {
262*03ce13f7SAndroid Build Coastguard Worker       // We currently only allow 32-bit fixups, and they usually have value = 0,
263*03ce13f7SAndroid Build Coastguard Worker       // so if fixup_ != nullptr, it shouldn't be classified as int8/16.
264*03ce13f7SAndroid Build Coastguard Worker       return fixup_ == nullptr && Utils::IsInt(8, value_);
265*03ce13f7SAndroid Build Coastguard Worker     }
is_uint8()266*03ce13f7SAndroid Build Coastguard Worker     bool is_uint8() const {
267*03ce13f7SAndroid Build Coastguard Worker       return fixup_ == nullptr && Utils::IsUint(8, value_);
268*03ce13f7SAndroid Build Coastguard Worker     }
is_uint16()269*03ce13f7SAndroid Build Coastguard Worker     bool is_uint16() const {
270*03ce13f7SAndroid Build Coastguard Worker       return fixup_ == nullptr && Utils::IsUint(16, value_);
271*03ce13f7SAndroid Build Coastguard Worker     }
272*03ce13f7SAndroid Build Coastguard Worker 
273*03ce13f7SAndroid Build Coastguard Worker   private:
274*03ce13f7SAndroid Build Coastguard Worker     const int32_t value_ = 0;
275*03ce13f7SAndroid Build Coastguard Worker     AssemblerFixup *fixup_ = nullptr;
276*03ce13f7SAndroid Build Coastguard Worker   };
277*03ce13f7SAndroid Build Coastguard Worker 
278*03ce13f7SAndroid Build Coastguard Worker   /// X86 allows near and far jumps.
279*03ce13f7SAndroid Build Coastguard Worker   class Label final : public Ice::Label {
280*03ce13f7SAndroid Build Coastguard Worker     Label(const Label &) = delete;
281*03ce13f7SAndroid Build Coastguard Worker     Label &operator=(const Label &) = delete;
282*03ce13f7SAndroid Build Coastguard Worker 
283*03ce13f7SAndroid Build Coastguard Worker   public:
284*03ce13f7SAndroid Build Coastguard Worker     Label() = default;
285*03ce13f7SAndroid Build Coastguard Worker     ~Label() = default;
286*03ce13f7SAndroid Build Coastguard Worker 
finalCheck()287*03ce13f7SAndroid Build Coastguard Worker     void finalCheck() const override {
288*03ce13f7SAndroid Build Coastguard Worker       Ice::Label::finalCheck();
289*03ce13f7SAndroid Build Coastguard Worker       assert(!hasNear());
290*03ce13f7SAndroid Build Coastguard Worker     }
291*03ce13f7SAndroid Build Coastguard Worker 
292*03ce13f7SAndroid Build Coastguard Worker     /// Returns the position of an earlier branch instruction which assumes that
293*03ce13f7SAndroid Build Coastguard Worker     /// this label is "near", and bumps iterator to the next near position.
getNearPosition()294*03ce13f7SAndroid Build Coastguard Worker     intptr_t getNearPosition() {
295*03ce13f7SAndroid Build Coastguard Worker       assert(hasNear());
296*03ce13f7SAndroid Build Coastguard Worker       intptr_t Pos = UnresolvedNearPositions.back();
297*03ce13f7SAndroid Build Coastguard Worker       UnresolvedNearPositions.pop_back();
298*03ce13f7SAndroid Build Coastguard Worker       return Pos;
299*03ce13f7SAndroid Build Coastguard Worker     }
300*03ce13f7SAndroid Build Coastguard Worker 
hasNear()301*03ce13f7SAndroid Build Coastguard Worker     bool hasNear() const { return !UnresolvedNearPositions.empty(); }
isUnused()302*03ce13f7SAndroid Build Coastguard Worker     bool isUnused() const override {
303*03ce13f7SAndroid Build Coastguard Worker       return Ice::Label::isUnused() && !hasNear();
304*03ce13f7SAndroid Build Coastguard Worker     }
305*03ce13f7SAndroid Build Coastguard Worker 
306*03ce13f7SAndroid Build Coastguard Worker   private:
307*03ce13f7SAndroid Build Coastguard Worker     friend class AssemblerX8632;
308*03ce13f7SAndroid Build Coastguard Worker 
nearLinkTo(const Assembler & Asm,intptr_t position)309*03ce13f7SAndroid Build Coastguard Worker     void nearLinkTo(const Assembler &Asm, intptr_t position) {
310*03ce13f7SAndroid Build Coastguard Worker       if (Asm.getPreliminary())
311*03ce13f7SAndroid Build Coastguard Worker         return;
312*03ce13f7SAndroid Build Coastguard Worker       assert(!isBound());
313*03ce13f7SAndroid Build Coastguard Worker       UnresolvedNearPositions.push_back(position);
314*03ce13f7SAndroid Build Coastguard Worker     }
315*03ce13f7SAndroid Build Coastguard Worker 
316*03ce13f7SAndroid Build Coastguard Worker     llvm::SmallVector<intptr_t, 20> UnresolvedNearPositions;
317*03ce13f7SAndroid Build Coastguard Worker   };
318*03ce13f7SAndroid Build Coastguard Worker 
319*03ce13f7SAndroid Build Coastguard Worker public:
320*03ce13f7SAndroid Build Coastguard Worker   ~AssemblerX8632() override;
321*03ce13f7SAndroid Build Coastguard Worker 
322*03ce13f7SAndroid Build Coastguard Worker   static const bool kNearJump = true;
323*03ce13f7SAndroid Build Coastguard Worker   static const bool kFarJump = false;
324*03ce13f7SAndroid Build Coastguard Worker 
325*03ce13f7SAndroid Build Coastguard Worker   void alignFunction() override;
326*03ce13f7SAndroid Build Coastguard Worker 
getBundleAlignLog2Bytes()327*03ce13f7SAndroid Build Coastguard Worker   SizeT getBundleAlignLog2Bytes() const override { return 5; }
328*03ce13f7SAndroid Build Coastguard Worker 
getAlignDirective()329*03ce13f7SAndroid Build Coastguard Worker   const char *getAlignDirective() const override { return ".p2align"; }
330*03ce13f7SAndroid Build Coastguard Worker 
getNonExecBundlePadding()331*03ce13f7SAndroid Build Coastguard Worker   llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override {
332*03ce13f7SAndroid Build Coastguard Worker     static const uint8_t Padding[] = {0xF4};
333*03ce13f7SAndroid Build Coastguard Worker     return llvm::ArrayRef<uint8_t>(Padding, 1);
334*03ce13f7SAndroid Build Coastguard Worker   }
335*03ce13f7SAndroid Build Coastguard Worker 
padWithNop(intptr_t Padding)336*03ce13f7SAndroid Build Coastguard Worker   void padWithNop(intptr_t Padding) override {
337*03ce13f7SAndroid Build Coastguard Worker     while (Padding > MAX_NOP_SIZE) {
338*03ce13f7SAndroid Build Coastguard Worker       nop(MAX_NOP_SIZE);
339*03ce13f7SAndroid Build Coastguard Worker       Padding -= MAX_NOP_SIZE;
340*03ce13f7SAndroid Build Coastguard Worker     }
341*03ce13f7SAndroid Build Coastguard Worker     if (Padding)
342*03ce13f7SAndroid Build Coastguard Worker       nop(Padding);
343*03ce13f7SAndroid Build Coastguard Worker   }
344*03ce13f7SAndroid Build Coastguard Worker 
345*03ce13f7SAndroid Build Coastguard Worker   Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override;
346*03ce13f7SAndroid Build Coastguard Worker   void bindCfgNodeLabel(const CfgNode *Node) override;
347*03ce13f7SAndroid Build Coastguard Worker   Label *getOrCreateCfgNodeLabel(SizeT Number);
348*03ce13f7SAndroid Build Coastguard Worker   Label *getOrCreateLocalLabel(SizeT Number);
349*03ce13f7SAndroid Build Coastguard Worker   void bindLocalLabel(SizeT Number);
350*03ce13f7SAndroid Build Coastguard Worker 
fixupIsPCRel(FixupKind Kind)351*03ce13f7SAndroid Build Coastguard Worker   bool fixupIsPCRel(FixupKind Kind) const override {
352*03ce13f7SAndroid Build Coastguard Worker     // Currently assuming this is the only PC-rel relocation type used.
353*03ce13f7SAndroid Build Coastguard Worker     // TODO(jpp): Traits.PcRelTypes.count(Kind) != 0
354*03ce13f7SAndroid Build Coastguard Worker     return Kind == FK_PcRel;
355*03ce13f7SAndroid Build Coastguard Worker   }
356*03ce13f7SAndroid Build Coastguard Worker 
357*03ce13f7SAndroid Build Coastguard Worker   // Operations to emit GPR instructions (and dispatch on operand type).
358*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitGPR = void (AssemblerX8632::*)(Type, GPRRegister);
359*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitAddr = void (AssemblerX8632::*)(Type, const AsmAddress &);
360*03ce13f7SAndroid Build Coastguard Worker   struct GPREmitterOneOp {
361*03ce13f7SAndroid Build Coastguard Worker     TypedEmitGPR Reg;
362*03ce13f7SAndroid Build Coastguard Worker     TypedEmitAddr Addr;
363*03ce13f7SAndroid Build Coastguard Worker   };
364*03ce13f7SAndroid Build Coastguard Worker 
365*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitGPRGPR = void (AssemblerX8632::*)(Type, GPRRegister,
366*03ce13f7SAndroid Build Coastguard Worker                                                    GPRRegister);
367*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitGPRAddr = void (AssemblerX8632::*)(Type, GPRRegister,
368*03ce13f7SAndroid Build Coastguard Worker                                                     const AsmAddress &);
369*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitGPRImm = void (AssemblerX8632::*)(Type, GPRRegister,
370*03ce13f7SAndroid Build Coastguard Worker                                                    const Immediate &);
371*03ce13f7SAndroid Build Coastguard Worker   struct GPREmitterRegOp {
372*03ce13f7SAndroid Build Coastguard Worker     TypedEmitGPRGPR GPRGPR;
373*03ce13f7SAndroid Build Coastguard Worker     TypedEmitGPRAddr GPRAddr;
374*03ce13f7SAndroid Build Coastguard Worker     TypedEmitGPRImm GPRImm;
375*03ce13f7SAndroid Build Coastguard Worker   };
376*03ce13f7SAndroid Build Coastguard Worker 
377*03ce13f7SAndroid Build Coastguard Worker   struct GPREmitterShiftOp {
378*03ce13f7SAndroid Build Coastguard Worker     // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are
379*03ce13f7SAndroid Build Coastguard Worker     // not. In practice, we always normalize the Dest to a Register first.
380*03ce13f7SAndroid Build Coastguard Worker     TypedEmitGPRGPR GPRGPR;
381*03ce13f7SAndroid Build Coastguard Worker     TypedEmitGPRImm GPRImm;
382*03ce13f7SAndroid Build Coastguard Worker   };
383*03ce13f7SAndroid Build Coastguard Worker 
384*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitGPRGPRImm = void (AssemblerX8632::*)(Type, GPRRegister,
385*03ce13f7SAndroid Build Coastguard Worker                                                       GPRRegister,
386*03ce13f7SAndroid Build Coastguard Worker                                                       const Immediate &);
387*03ce13f7SAndroid Build Coastguard Worker   struct GPREmitterShiftD {
388*03ce13f7SAndroid Build Coastguard Worker     // Technically AddrGPR and AddrGPRImm are also allowed, but in practice we
389*03ce13f7SAndroid Build Coastguard Worker     // always normalize Dest to a Register first.
390*03ce13f7SAndroid Build Coastguard Worker     TypedEmitGPRGPR GPRGPR;
391*03ce13f7SAndroid Build Coastguard Worker     TypedEmitGPRGPRImm GPRGPRImm;
392*03ce13f7SAndroid Build Coastguard Worker   };
393*03ce13f7SAndroid Build Coastguard Worker 
394*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitAddrGPR = void (AssemblerX8632::*)(Type, const AsmAddress &,
395*03ce13f7SAndroid Build Coastguard Worker                                                     GPRRegister);
396*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitAddrImm = void (AssemblerX8632::*)(Type, const AsmAddress &,
397*03ce13f7SAndroid Build Coastguard Worker                                                     const Immediate &);
398*03ce13f7SAndroid Build Coastguard Worker   struct GPREmitterAddrOp {
399*03ce13f7SAndroid Build Coastguard Worker     TypedEmitAddrGPR AddrGPR;
400*03ce13f7SAndroid Build Coastguard Worker     TypedEmitAddrImm AddrImm;
401*03ce13f7SAndroid Build Coastguard Worker   };
402*03ce13f7SAndroid Build Coastguard Worker 
403*03ce13f7SAndroid Build Coastguard Worker   // Operations to emit XMM instructions (and dispatch on operand type).
404*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitXmmXmm = void (AssemblerX8632::*)(Type, XmmRegister,
405*03ce13f7SAndroid Build Coastguard Worker                                                    XmmRegister);
406*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitXmmAddr = void (AssemblerX8632::*)(Type, XmmRegister,
407*03ce13f7SAndroid Build Coastguard Worker                                                     const AsmAddress &);
408*03ce13f7SAndroid Build Coastguard Worker   struct XmmEmitterRegOp {
409*03ce13f7SAndroid Build Coastguard Worker     TypedEmitXmmXmm XmmXmm;
410*03ce13f7SAndroid Build Coastguard Worker     TypedEmitXmmAddr XmmAddr;
411*03ce13f7SAndroid Build Coastguard Worker   };
412*03ce13f7SAndroid Build Coastguard Worker 
413*03ce13f7SAndroid Build Coastguard Worker   using EmitXmmXmm = void (AssemblerX8632::*)(XmmRegister, XmmRegister);
414*03ce13f7SAndroid Build Coastguard Worker   using EmitXmmAddr = void (AssemblerX8632::*)(XmmRegister, const AsmAddress &);
415*03ce13f7SAndroid Build Coastguard Worker   using EmitAddrXmm = void (AssemblerX8632::*)(const AsmAddress &, XmmRegister);
416*03ce13f7SAndroid Build Coastguard Worker   struct XmmEmitterMovOps {
417*03ce13f7SAndroid Build Coastguard Worker     EmitXmmXmm XmmXmm;
418*03ce13f7SAndroid Build Coastguard Worker     EmitXmmAddr XmmAddr;
419*03ce13f7SAndroid Build Coastguard Worker     EmitAddrXmm AddrXmm;
420*03ce13f7SAndroid Build Coastguard Worker   };
421*03ce13f7SAndroid Build Coastguard Worker 
422*03ce13f7SAndroid Build Coastguard Worker   using TypedEmitXmmImm = void (AssemblerX8632::*)(Type, XmmRegister,
423*03ce13f7SAndroid Build Coastguard Worker                                                    const Immediate &);
424*03ce13f7SAndroid Build Coastguard Worker 
425*03ce13f7SAndroid Build Coastguard Worker   struct XmmEmitterShiftOp {
426*03ce13f7SAndroid Build Coastguard Worker     TypedEmitXmmXmm XmmXmm;
427*03ce13f7SAndroid Build Coastguard Worker     TypedEmitXmmAddr XmmAddr;
428*03ce13f7SAndroid Build Coastguard Worker     TypedEmitXmmImm XmmImm;
429*03ce13f7SAndroid Build Coastguard Worker   };
430*03ce13f7SAndroid Build Coastguard Worker 
431*03ce13f7SAndroid Build Coastguard Worker   // Cross Xmm/GPR cast instructions.
432*03ce13f7SAndroid Build Coastguard Worker   template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp {
433*03ce13f7SAndroid Build Coastguard Worker     using TypedEmitRegs = void (AssemblerX8632::*)(Type, DReg_t, Type, SReg_t);
434*03ce13f7SAndroid Build Coastguard Worker     using TypedEmitAddr = void (AssemblerX8632::*)(Type, DReg_t, Type,
435*03ce13f7SAndroid Build Coastguard Worker                                                    const AsmAddress &);
436*03ce13f7SAndroid Build Coastguard Worker 
437*03ce13f7SAndroid Build Coastguard Worker     TypedEmitRegs RegReg;
438*03ce13f7SAndroid Build Coastguard Worker     TypedEmitAddr RegAddr;
439*03ce13f7SAndroid Build Coastguard Worker   };
440*03ce13f7SAndroid Build Coastguard Worker 
441*03ce13f7SAndroid Build Coastguard Worker   // Three operand (potentially) cross Xmm/GPR instructions. The last operand
442*03ce13f7SAndroid Build Coastguard Worker   // must be an immediate.
443*03ce13f7SAndroid Build Coastguard Worker   template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter {
444*03ce13f7SAndroid Build Coastguard Worker     using TypedEmitRegRegImm = void (AssemblerX8632::*)(Type, DReg_t, SReg_t,
445*03ce13f7SAndroid Build Coastguard Worker                                                         const Immediate &);
446*03ce13f7SAndroid Build Coastguard Worker     using TypedEmitRegAddrImm = void (AssemblerX8632::*)(Type, DReg_t,
447*03ce13f7SAndroid Build Coastguard Worker                                                          const AsmAddress &,
448*03ce13f7SAndroid Build Coastguard Worker                                                          const Immediate &);
449*03ce13f7SAndroid Build Coastguard Worker 
450*03ce13f7SAndroid Build Coastguard Worker     TypedEmitRegRegImm RegRegImm;
451*03ce13f7SAndroid Build Coastguard Worker     TypedEmitRegAddrImm RegAddrImm;
452*03ce13f7SAndroid Build Coastguard Worker   };
453*03ce13f7SAndroid Build Coastguard Worker 
454*03ce13f7SAndroid Build Coastguard Worker   /*
455*03ce13f7SAndroid Build Coastguard Worker    * Emit Machine Instructions.
456*03ce13f7SAndroid Build Coastguard Worker    */
457*03ce13f7SAndroid Build Coastguard Worker   void call(GPRRegister reg);
458*03ce13f7SAndroid Build Coastguard Worker   void call(const AsmAddress &address);
459*03ce13f7SAndroid Build Coastguard Worker   void call(const ConstantRelocatable *label); // not testable.
460*03ce13f7SAndroid Build Coastguard Worker   void call(const Immediate &abs_address);
461*03ce13f7SAndroid Build Coastguard Worker 
462*03ce13f7SAndroid Build Coastguard Worker   static const intptr_t kCallExternalLabelSize = 5;
463*03ce13f7SAndroid Build Coastguard Worker 
464*03ce13f7SAndroid Build Coastguard Worker   void pushl(GPRRegister reg);
465*03ce13f7SAndroid Build Coastguard Worker   void pushl(const Immediate &Imm);
466*03ce13f7SAndroid Build Coastguard Worker   void pushl(const ConstantRelocatable *Label);
467*03ce13f7SAndroid Build Coastguard Worker 
468*03ce13f7SAndroid Build Coastguard Worker   void popl(GPRRegister reg);
469*03ce13f7SAndroid Build Coastguard Worker   void popl(const AsmAddress &address);
470*03ce13f7SAndroid Build Coastguard Worker 
471*03ce13f7SAndroid Build Coastguard Worker   void pushal();
472*03ce13f7SAndroid Build Coastguard Worker   void popal();
473*03ce13f7SAndroid Build Coastguard Worker 
474*03ce13f7SAndroid Build Coastguard Worker   void setcc(BrCond condition, ByteRegister dst);
475*03ce13f7SAndroid Build Coastguard Worker   void setcc(BrCond condition, const AsmAddress &address);
476*03ce13f7SAndroid Build Coastguard Worker 
477*03ce13f7SAndroid Build Coastguard Worker   void mov(Type Ty, GPRRegister dst, const Immediate &src);
478*03ce13f7SAndroid Build Coastguard Worker   void mov(Type Ty, GPRRegister dst, GPRRegister src);
479*03ce13f7SAndroid Build Coastguard Worker   void mov(Type Ty, GPRRegister dst, const AsmAddress &src);
480*03ce13f7SAndroid Build Coastguard Worker   void mov(Type Ty, const AsmAddress &dst, GPRRegister src);
481*03ce13f7SAndroid Build Coastguard Worker   void mov(Type Ty, const AsmAddress &dst, const Immediate &imm);
482*03ce13f7SAndroid Build Coastguard Worker 
483*03ce13f7SAndroid Build Coastguard Worker   void movzx(Type Ty, GPRRegister dst, GPRRegister src);
484*03ce13f7SAndroid Build Coastguard Worker   void movzx(Type Ty, GPRRegister dst, const AsmAddress &src);
485*03ce13f7SAndroid Build Coastguard Worker   void movsx(Type Ty, GPRRegister dst, GPRRegister src);
486*03ce13f7SAndroid Build Coastguard Worker   void movsx(Type Ty, GPRRegister dst, const AsmAddress &src);
487*03ce13f7SAndroid Build Coastguard Worker 
488*03ce13f7SAndroid Build Coastguard Worker   void lea(Type Ty, GPRRegister dst, const AsmAddress &src);
489*03ce13f7SAndroid Build Coastguard Worker 
490*03ce13f7SAndroid Build Coastguard Worker   void cmov(Type Ty, BrCond cond, GPRRegister dst, GPRRegister src);
491*03ce13f7SAndroid Build Coastguard Worker   void cmov(Type Ty, BrCond cond, GPRRegister dst, const AsmAddress &src);
492*03ce13f7SAndroid Build Coastguard Worker 
493*03ce13f7SAndroid Build Coastguard Worker   void rep_movsb();
494*03ce13f7SAndroid Build Coastguard Worker 
495*03ce13f7SAndroid Build Coastguard Worker   void movss(Type Ty, XmmRegister dst, const AsmAddress &src);
496*03ce13f7SAndroid Build Coastguard Worker   void movss(Type Ty, const AsmAddress &dst, XmmRegister src);
497*03ce13f7SAndroid Build Coastguard Worker   void movss(Type Ty, XmmRegister dst, XmmRegister src);
498*03ce13f7SAndroid Build Coastguard Worker 
499*03ce13f7SAndroid Build Coastguard Worker   void movd(Type SrcTy, XmmRegister dst, GPRRegister src);
500*03ce13f7SAndroid Build Coastguard Worker   void movd(Type SrcTy, XmmRegister dst, const AsmAddress &src);
501*03ce13f7SAndroid Build Coastguard Worker   void movd(Type DestTy, GPRRegister dst, XmmRegister src);
502*03ce13f7SAndroid Build Coastguard Worker   void movd(Type DestTy, const AsmAddress &dst, XmmRegister src);
503*03ce13f7SAndroid Build Coastguard Worker 
504*03ce13f7SAndroid Build Coastguard Worker   void movq(XmmRegister dst, XmmRegister src);
505*03ce13f7SAndroid Build Coastguard Worker   void movq(const AsmAddress &dst, XmmRegister src);
506*03ce13f7SAndroid Build Coastguard Worker   void movq(XmmRegister dst, const AsmAddress &src);
507*03ce13f7SAndroid Build Coastguard Worker 
508*03ce13f7SAndroid Build Coastguard Worker   void addss(Type Ty, XmmRegister dst, XmmRegister src);
509*03ce13f7SAndroid Build Coastguard Worker   void addss(Type Ty, XmmRegister dst, const AsmAddress &src);
510*03ce13f7SAndroid Build Coastguard Worker   void subss(Type Ty, XmmRegister dst, XmmRegister src);
511*03ce13f7SAndroid Build Coastguard Worker   void subss(Type Ty, XmmRegister dst, const AsmAddress &src);
512*03ce13f7SAndroid Build Coastguard Worker   void mulss(Type Ty, XmmRegister dst, XmmRegister src);
513*03ce13f7SAndroid Build Coastguard Worker   void mulss(Type Ty, XmmRegister dst, const AsmAddress &src);
514*03ce13f7SAndroid Build Coastguard Worker   void divss(Type Ty, XmmRegister dst, XmmRegister src);
515*03ce13f7SAndroid Build Coastguard Worker   void divss(Type Ty, XmmRegister dst, const AsmAddress &src);
516*03ce13f7SAndroid Build Coastguard Worker 
517*03ce13f7SAndroid Build Coastguard Worker   void movaps(XmmRegister dst, XmmRegister src);
518*03ce13f7SAndroid Build Coastguard Worker 
519*03ce13f7SAndroid Build Coastguard Worker   void movups(XmmRegister dst, XmmRegister src);
520*03ce13f7SAndroid Build Coastguard Worker   void movups(XmmRegister dst, const AsmAddress &src);
521*03ce13f7SAndroid Build Coastguard Worker   void movups(const AsmAddress &dst, XmmRegister src);
522*03ce13f7SAndroid Build Coastguard Worker 
523*03ce13f7SAndroid Build Coastguard Worker   void padd(Type Ty, XmmRegister dst, XmmRegister src);
524*03ce13f7SAndroid Build Coastguard Worker   void padd(Type Ty, XmmRegister dst, const AsmAddress &src);
525*03ce13f7SAndroid Build Coastguard Worker   void padds(Type Ty, XmmRegister dst, XmmRegister src);
526*03ce13f7SAndroid Build Coastguard Worker   void padds(Type Ty, XmmRegister dst, const AsmAddress &src);
527*03ce13f7SAndroid Build Coastguard Worker   void paddus(Type Ty, XmmRegister dst, XmmRegister src);
528*03ce13f7SAndroid Build Coastguard Worker   void paddus(Type Ty, XmmRegister dst, const AsmAddress &src);
529*03ce13f7SAndroid Build Coastguard Worker   void pand(Type Ty, XmmRegister dst, XmmRegister src);
530*03ce13f7SAndroid Build Coastguard Worker   void pand(Type Ty, XmmRegister dst, const AsmAddress &src);
531*03ce13f7SAndroid Build Coastguard Worker   void pandn(Type Ty, XmmRegister dst, XmmRegister src);
532*03ce13f7SAndroid Build Coastguard Worker   void pandn(Type Ty, XmmRegister dst, const AsmAddress &src);
533*03ce13f7SAndroid Build Coastguard Worker   void pmull(Type Ty, XmmRegister dst, XmmRegister src);
534*03ce13f7SAndroid Build Coastguard Worker   void pmull(Type Ty, XmmRegister dst, const AsmAddress &src);
535*03ce13f7SAndroid Build Coastguard Worker   void pmulhw(Type Ty, XmmRegister dst, XmmRegister src);
536*03ce13f7SAndroid Build Coastguard Worker   void pmulhw(Type Ty, XmmRegister dst, const AsmAddress &src);
537*03ce13f7SAndroid Build Coastguard Worker   void pmulhuw(Type Ty, XmmRegister dst, XmmRegister src);
538*03ce13f7SAndroid Build Coastguard Worker   void pmulhuw(Type Ty, XmmRegister dst, const AsmAddress &src);
539*03ce13f7SAndroid Build Coastguard Worker   void pmaddwd(Type Ty, XmmRegister dst, XmmRegister src);
540*03ce13f7SAndroid Build Coastguard Worker   void pmaddwd(Type Ty, XmmRegister dst, const AsmAddress &src);
541*03ce13f7SAndroid Build Coastguard Worker   void pmuludq(Type Ty, XmmRegister dst, XmmRegister src);
542*03ce13f7SAndroid Build Coastguard Worker   void pmuludq(Type Ty, XmmRegister dst, const AsmAddress &src);
543*03ce13f7SAndroid Build Coastguard Worker   void por(Type Ty, XmmRegister dst, XmmRegister src);
544*03ce13f7SAndroid Build Coastguard Worker   void por(Type Ty, XmmRegister dst, const AsmAddress &src);
545*03ce13f7SAndroid Build Coastguard Worker   void psub(Type Ty, XmmRegister dst, XmmRegister src);
546*03ce13f7SAndroid Build Coastguard Worker   void psub(Type Ty, XmmRegister dst, const AsmAddress &src);
547*03ce13f7SAndroid Build Coastguard Worker   void psubs(Type Ty, XmmRegister dst, XmmRegister src);
548*03ce13f7SAndroid Build Coastguard Worker   void psubs(Type Ty, XmmRegister dst, const AsmAddress &src);
549*03ce13f7SAndroid Build Coastguard Worker   void psubus(Type Ty, XmmRegister dst, XmmRegister src);
550*03ce13f7SAndroid Build Coastguard Worker   void psubus(Type Ty, XmmRegister dst, const AsmAddress &src);
551*03ce13f7SAndroid Build Coastguard Worker   void pxor(Type Ty, XmmRegister dst, XmmRegister src);
552*03ce13f7SAndroid Build Coastguard Worker   void pxor(Type Ty, XmmRegister dst, const AsmAddress &src);
553*03ce13f7SAndroid Build Coastguard Worker 
554*03ce13f7SAndroid Build Coastguard Worker   void psll(Type Ty, XmmRegister dst, XmmRegister src);
555*03ce13f7SAndroid Build Coastguard Worker   void psll(Type Ty, XmmRegister dst, const AsmAddress &src);
556*03ce13f7SAndroid Build Coastguard Worker   void psll(Type Ty, XmmRegister dst, const Immediate &src);
557*03ce13f7SAndroid Build Coastguard Worker 
558*03ce13f7SAndroid Build Coastguard Worker   void psra(Type Ty, XmmRegister dst, XmmRegister src);
559*03ce13f7SAndroid Build Coastguard Worker   void psra(Type Ty, XmmRegister dst, const AsmAddress &src);
560*03ce13f7SAndroid Build Coastguard Worker   void psra(Type Ty, XmmRegister dst, const Immediate &src);
561*03ce13f7SAndroid Build Coastguard Worker   void psrl(Type Ty, XmmRegister dst, XmmRegister src);
562*03ce13f7SAndroid Build Coastguard Worker   void psrl(Type Ty, XmmRegister dst, const AsmAddress &src);
563*03ce13f7SAndroid Build Coastguard Worker   void psrl(Type Ty, XmmRegister dst, const Immediate &src);
564*03ce13f7SAndroid Build Coastguard Worker 
565*03ce13f7SAndroid Build Coastguard Worker   void addps(Type Ty, XmmRegister dst, XmmRegister src);
566*03ce13f7SAndroid Build Coastguard Worker   void addps(Type Ty, XmmRegister dst, const AsmAddress &src);
567*03ce13f7SAndroid Build Coastguard Worker   void subps(Type Ty, XmmRegister dst, XmmRegister src);
568*03ce13f7SAndroid Build Coastguard Worker   void subps(Type Ty, XmmRegister dst, const AsmAddress &src);
569*03ce13f7SAndroid Build Coastguard Worker   void divps(Type Ty, XmmRegister dst, XmmRegister src);
570*03ce13f7SAndroid Build Coastguard Worker   void divps(Type Ty, XmmRegister dst, const AsmAddress &src);
571*03ce13f7SAndroid Build Coastguard Worker   void mulps(Type Ty, XmmRegister dst, XmmRegister src);
572*03ce13f7SAndroid Build Coastguard Worker   void mulps(Type Ty, XmmRegister dst, const AsmAddress &src);
573*03ce13f7SAndroid Build Coastguard Worker   void minps(Type Ty, XmmRegister dst, const AsmAddress &src);
574*03ce13f7SAndroid Build Coastguard Worker   void minps(Type Ty, XmmRegister dst, XmmRegister src);
575*03ce13f7SAndroid Build Coastguard Worker   void minss(Type Ty, XmmRegister dst, const AsmAddress &src);
576*03ce13f7SAndroid Build Coastguard Worker   void minss(Type Ty, XmmRegister dst, XmmRegister src);
577*03ce13f7SAndroid Build Coastguard Worker   void maxps(Type Ty, XmmRegister dst, const AsmAddress &src);
578*03ce13f7SAndroid Build Coastguard Worker   void maxps(Type Ty, XmmRegister dst, XmmRegister src);
579*03ce13f7SAndroid Build Coastguard Worker   void maxss(Type Ty, XmmRegister dst, const AsmAddress &src);
580*03ce13f7SAndroid Build Coastguard Worker   void maxss(Type Ty, XmmRegister dst, XmmRegister src);
581*03ce13f7SAndroid Build Coastguard Worker   void andnps(Type Ty, XmmRegister dst, const AsmAddress &src);
582*03ce13f7SAndroid Build Coastguard Worker   void andnps(Type Ty, XmmRegister dst, XmmRegister src);
583*03ce13f7SAndroid Build Coastguard Worker   void andps(Type Ty, XmmRegister dst, const AsmAddress &src);
584*03ce13f7SAndroid Build Coastguard Worker   void andps(Type Ty, XmmRegister dst, XmmRegister src);
585*03ce13f7SAndroid Build Coastguard Worker   void orps(Type Ty, XmmRegister dst, const AsmAddress &src);
586*03ce13f7SAndroid Build Coastguard Worker   void orps(Type Ty, XmmRegister dst, XmmRegister src);
587*03ce13f7SAndroid Build Coastguard Worker 
588*03ce13f7SAndroid Build Coastguard Worker   void blendvps(Type Ty, XmmRegister dst, XmmRegister src);
589*03ce13f7SAndroid Build Coastguard Worker   void blendvps(Type Ty, XmmRegister dst, const AsmAddress &src);
590*03ce13f7SAndroid Build Coastguard Worker   void pblendvb(Type Ty, XmmRegister dst, XmmRegister src);
591*03ce13f7SAndroid Build Coastguard Worker   void pblendvb(Type Ty, XmmRegister dst, const AsmAddress &src);
592*03ce13f7SAndroid Build Coastguard Worker 
593*03ce13f7SAndroid Build Coastguard Worker   void cmpps(Type Ty, XmmRegister dst, XmmRegister src, CmppsCond CmpCondition);
594*03ce13f7SAndroid Build Coastguard Worker   void cmpps(Type Ty, XmmRegister dst, const AsmAddress &src,
595*03ce13f7SAndroid Build Coastguard Worker              CmppsCond CmpCondition);
596*03ce13f7SAndroid Build Coastguard Worker 
597*03ce13f7SAndroid Build Coastguard Worker   void sqrtps(XmmRegister dst);
598*03ce13f7SAndroid Build Coastguard Worker   void rsqrtps(XmmRegister dst);
599*03ce13f7SAndroid Build Coastguard Worker   void reciprocalps(XmmRegister dst);
600*03ce13f7SAndroid Build Coastguard Worker 
601*03ce13f7SAndroid Build Coastguard Worker   void movhlps(XmmRegister dst, XmmRegister src);
602*03ce13f7SAndroid Build Coastguard Worker   void movlhps(XmmRegister dst, XmmRegister src);
603*03ce13f7SAndroid Build Coastguard Worker   void unpcklps(XmmRegister dst, XmmRegister src);
604*03ce13f7SAndroid Build Coastguard Worker   void unpckhps(XmmRegister dst, XmmRegister src);
605*03ce13f7SAndroid Build Coastguard Worker   void unpcklpd(XmmRegister dst, XmmRegister src);
606*03ce13f7SAndroid Build Coastguard Worker   void unpckhpd(XmmRegister dst, XmmRegister src);
607*03ce13f7SAndroid Build Coastguard Worker 
608*03ce13f7SAndroid Build Coastguard Worker   void set1ps(XmmRegister dst, GPRRegister tmp, const Immediate &imm);
609*03ce13f7SAndroid Build Coastguard Worker 
610*03ce13f7SAndroid Build Coastguard Worker   void sqrtpd(XmmRegister dst);
611*03ce13f7SAndroid Build Coastguard Worker 
612*03ce13f7SAndroid Build Coastguard Worker   void pshufb(Type Ty, XmmRegister dst, XmmRegister src);
613*03ce13f7SAndroid Build Coastguard Worker   void pshufb(Type Ty, XmmRegister dst, const AsmAddress &src);
614*03ce13f7SAndroid Build Coastguard Worker   void pshufd(Type Ty, XmmRegister dst, XmmRegister src, const Immediate &mask);
615*03ce13f7SAndroid Build Coastguard Worker   void pshufd(Type Ty, XmmRegister dst, const AsmAddress &src,
616*03ce13f7SAndroid Build Coastguard Worker               const Immediate &mask);
617*03ce13f7SAndroid Build Coastguard Worker   void punpckl(Type Ty, XmmRegister Dst, XmmRegister Src);
618*03ce13f7SAndroid Build Coastguard Worker   void punpckl(Type Ty, XmmRegister Dst, const AsmAddress &Src);
619*03ce13f7SAndroid Build Coastguard Worker   void punpckh(Type Ty, XmmRegister Dst, XmmRegister Src);
620*03ce13f7SAndroid Build Coastguard Worker   void punpckh(Type Ty, XmmRegister Dst, const AsmAddress &Src);
621*03ce13f7SAndroid Build Coastguard Worker   void packss(Type Ty, XmmRegister Dst, XmmRegister Src);
622*03ce13f7SAndroid Build Coastguard Worker   void packss(Type Ty, XmmRegister Dst, const AsmAddress &Src);
623*03ce13f7SAndroid Build Coastguard Worker   void packus(Type Ty, XmmRegister Dst, XmmRegister Src);
624*03ce13f7SAndroid Build Coastguard Worker   void packus(Type Ty, XmmRegister Dst, const AsmAddress &Src);
625*03ce13f7SAndroid Build Coastguard Worker   void shufps(Type Ty, XmmRegister dst, XmmRegister src, const Immediate &mask);
626*03ce13f7SAndroid Build Coastguard Worker   void shufps(Type Ty, XmmRegister dst, const AsmAddress &src,
627*03ce13f7SAndroid Build Coastguard Worker               const Immediate &mask);
628*03ce13f7SAndroid Build Coastguard Worker 
629*03ce13f7SAndroid Build Coastguard Worker   void cvtdq2ps(Type, XmmRegister dst, XmmRegister src);
630*03ce13f7SAndroid Build Coastguard Worker   void cvtdq2ps(Type, XmmRegister dst, const AsmAddress &src);
631*03ce13f7SAndroid Build Coastguard Worker 
632*03ce13f7SAndroid Build Coastguard Worker   void cvttps2dq(Type, XmmRegister dst, XmmRegister src);
633*03ce13f7SAndroid Build Coastguard Worker   void cvttps2dq(Type, XmmRegister dst, const AsmAddress &src);
634*03ce13f7SAndroid Build Coastguard Worker 
635*03ce13f7SAndroid Build Coastguard Worker   void cvtps2dq(Type, XmmRegister dst, XmmRegister src);
636*03ce13f7SAndroid Build Coastguard Worker   void cvtps2dq(Type, XmmRegister dst, const AsmAddress &src);
637*03ce13f7SAndroid Build Coastguard Worker 
638*03ce13f7SAndroid Build Coastguard Worker   void cvtsi2ss(Type DestTy, XmmRegister dst, Type SrcTy, GPRRegister src);
639*03ce13f7SAndroid Build Coastguard Worker   void cvtsi2ss(Type DestTy, XmmRegister dst, Type SrcTy,
640*03ce13f7SAndroid Build Coastguard Worker                 const AsmAddress &src);
641*03ce13f7SAndroid Build Coastguard Worker 
642*03ce13f7SAndroid Build Coastguard Worker   void cvtfloat2float(Type SrcTy, XmmRegister dst, XmmRegister src);
643*03ce13f7SAndroid Build Coastguard Worker   void cvtfloat2float(Type SrcTy, XmmRegister dst, const AsmAddress &src);
644*03ce13f7SAndroid Build Coastguard Worker 
645*03ce13f7SAndroid Build Coastguard Worker   void cvttss2si(Type DestTy, GPRRegister dst, Type SrcTy, XmmRegister src);
646*03ce13f7SAndroid Build Coastguard Worker   void cvttss2si(Type DestTy, GPRRegister dst, Type SrcTy,
647*03ce13f7SAndroid Build Coastguard Worker                  const AsmAddress &src);
648*03ce13f7SAndroid Build Coastguard Worker 
649*03ce13f7SAndroid Build Coastguard Worker   void cvtss2si(Type DestTy, GPRRegister dst, Type SrcTy, XmmRegister src);
650*03ce13f7SAndroid Build Coastguard Worker   void cvtss2si(Type DestTy, GPRRegister dst, Type SrcTy,
651*03ce13f7SAndroid Build Coastguard Worker                 const AsmAddress &src);
652*03ce13f7SAndroid Build Coastguard Worker 
653*03ce13f7SAndroid Build Coastguard Worker   void ucomiss(Type Ty, XmmRegister a, XmmRegister b);
654*03ce13f7SAndroid Build Coastguard Worker   void ucomiss(Type Ty, XmmRegister a, const AsmAddress &b);
655*03ce13f7SAndroid Build Coastguard Worker 
656*03ce13f7SAndroid Build Coastguard Worker   void movmsk(Type Ty, GPRRegister dst, XmmRegister src);
657*03ce13f7SAndroid Build Coastguard Worker 
658*03ce13f7SAndroid Build Coastguard Worker   void sqrt(Type Ty, XmmRegister dst, const AsmAddress &src);
659*03ce13f7SAndroid Build Coastguard Worker   void sqrt(Type Ty, XmmRegister dst, XmmRegister src);
660*03ce13f7SAndroid Build Coastguard Worker 
661*03ce13f7SAndroid Build Coastguard Worker   void xorps(Type Ty, XmmRegister dst, const AsmAddress &src);
662*03ce13f7SAndroid Build Coastguard Worker   void xorps(Type Ty, XmmRegister dst, XmmRegister src);
663*03ce13f7SAndroid Build Coastguard Worker 
664*03ce13f7SAndroid Build Coastguard Worker   void insertps(Type Ty, XmmRegister dst, XmmRegister src,
665*03ce13f7SAndroid Build Coastguard Worker                 const Immediate &imm);
666*03ce13f7SAndroid Build Coastguard Worker   void insertps(Type Ty, XmmRegister dst, const AsmAddress &src,
667*03ce13f7SAndroid Build Coastguard Worker                 const Immediate &imm);
668*03ce13f7SAndroid Build Coastguard Worker 
669*03ce13f7SAndroid Build Coastguard Worker   void pinsr(Type Ty, XmmRegister dst, GPRRegister src, const Immediate &imm);
670*03ce13f7SAndroid Build Coastguard Worker   void pinsr(Type Ty, XmmRegister dst, const AsmAddress &src,
671*03ce13f7SAndroid Build Coastguard Worker              const Immediate &imm);
672*03ce13f7SAndroid Build Coastguard Worker 
673*03ce13f7SAndroid Build Coastguard Worker   void pextr(Type Ty, GPRRegister dst, XmmRegister src, const Immediate &imm);
674*03ce13f7SAndroid Build Coastguard Worker 
675*03ce13f7SAndroid Build Coastguard Worker   void pmovsxdq(XmmRegister dst, XmmRegister src);
676*03ce13f7SAndroid Build Coastguard Worker 
677*03ce13f7SAndroid Build Coastguard Worker   void pcmpeq(Type Ty, XmmRegister dst, XmmRegister src);
678*03ce13f7SAndroid Build Coastguard Worker   void pcmpeq(Type Ty, XmmRegister dst, const AsmAddress &src);
679*03ce13f7SAndroid Build Coastguard Worker   void pcmpgt(Type Ty, XmmRegister dst, XmmRegister src);
680*03ce13f7SAndroid Build Coastguard Worker   void pcmpgt(Type Ty, XmmRegister dst, const AsmAddress &src);
681*03ce13f7SAndroid Build Coastguard Worker 
682*03ce13f7SAndroid Build Coastguard Worker   enum RoundingMode {
683*03ce13f7SAndroid Build Coastguard Worker     kRoundToNearest = 0x0,
684*03ce13f7SAndroid Build Coastguard Worker     kRoundDown = 0x1,
685*03ce13f7SAndroid Build Coastguard Worker     kRoundUp = 0x2,
686*03ce13f7SAndroid Build Coastguard Worker     kRoundToZero = 0x3
687*03ce13f7SAndroid Build Coastguard Worker   };
688*03ce13f7SAndroid Build Coastguard Worker   void round(Type Ty, XmmRegister dst, XmmRegister src, const Immediate &mode);
689*03ce13f7SAndroid Build Coastguard Worker   void round(Type Ty, XmmRegister dst, const AsmAddress &src,
690*03ce13f7SAndroid Build Coastguard Worker              const Immediate &mode);
691*03ce13f7SAndroid Build Coastguard Worker 
692*03ce13f7SAndroid Build Coastguard Worker   //----------------------------------------------------------------------------
693*03ce13f7SAndroid Build Coastguard Worker   //
694*03ce13f7SAndroid Build Coastguard Worker   // Begin: X87 instructions.
695*03ce13f7SAndroid Build Coastguard Worker   //
696*03ce13f7SAndroid Build Coastguard Worker   //----------------------------------------------------------------------------
697*03ce13f7SAndroid Build Coastguard Worker   void fld(Type Ty, const AsmAddress &src);
698*03ce13f7SAndroid Build Coastguard Worker   void fstp(Type Ty, const AsmAddress &dst);
699*03ce13f7SAndroid Build Coastguard Worker   void fstp(RegX8632::X87STRegister st);
700*03ce13f7SAndroid Build Coastguard Worker 
701*03ce13f7SAndroid Build Coastguard Worker   void fnstcw(const AsmAddress &dst);
702*03ce13f7SAndroid Build Coastguard Worker   void fldcw(const AsmAddress &src);
703*03ce13f7SAndroid Build Coastguard Worker 
704*03ce13f7SAndroid Build Coastguard Worker   void fistpl(const AsmAddress &dst);
705*03ce13f7SAndroid Build Coastguard Worker   void fistps(const AsmAddress &dst);
706*03ce13f7SAndroid Build Coastguard Worker   void fildl(const AsmAddress &src);
707*03ce13f7SAndroid Build Coastguard Worker   void filds(const AsmAddress &src);
708*03ce13f7SAndroid Build Coastguard Worker 
709*03ce13f7SAndroid Build Coastguard Worker   void fincstp();
710*03ce13f7SAndroid Build Coastguard Worker   //----------------------------------------------------------------------------
711*03ce13f7SAndroid Build Coastguard Worker   //
712*03ce13f7SAndroid Build Coastguard Worker   // End: X87 instructions.
713*03ce13f7SAndroid Build Coastguard Worker   //
714*03ce13f7SAndroid Build Coastguard Worker   //----------------------------------------------------------------------------
715*03ce13f7SAndroid Build Coastguard Worker 
716*03ce13f7SAndroid Build Coastguard Worker   void cmp(Type Ty, GPRRegister reg0, GPRRegister reg1);
717*03ce13f7SAndroid Build Coastguard Worker   void cmp(Type Ty, GPRRegister reg, const AsmAddress &address);
718*03ce13f7SAndroid Build Coastguard Worker   void cmp(Type Ty, GPRRegister reg, const Immediate &imm);
719*03ce13f7SAndroid Build Coastguard Worker   void cmp(Type Ty, const AsmAddress &address, GPRRegister reg);
720*03ce13f7SAndroid Build Coastguard Worker   void cmp(Type Ty, const AsmAddress &address, const Immediate &imm);
721*03ce13f7SAndroid Build Coastguard Worker 
722*03ce13f7SAndroid Build Coastguard Worker   void test(Type Ty, GPRRegister reg0, GPRRegister reg1);
723*03ce13f7SAndroid Build Coastguard Worker   void test(Type Ty, GPRRegister reg, const Immediate &imm);
724*03ce13f7SAndroid Build Coastguard Worker   void test(Type Ty, const AsmAddress &address, GPRRegister reg);
725*03ce13f7SAndroid Build Coastguard Worker   void test(Type Ty, const AsmAddress &address, const Immediate &imm);
726*03ce13f7SAndroid Build Coastguard Worker 
727*03ce13f7SAndroid Build Coastguard Worker   void And(Type Ty, GPRRegister dst, GPRRegister src);
728*03ce13f7SAndroid Build Coastguard Worker   void And(Type Ty, GPRRegister dst, const AsmAddress &address);
729*03ce13f7SAndroid Build Coastguard Worker   void And(Type Ty, GPRRegister dst, const Immediate &imm);
730*03ce13f7SAndroid Build Coastguard Worker   void And(Type Ty, const AsmAddress &address, GPRRegister reg);
731*03ce13f7SAndroid Build Coastguard Worker   void And(Type Ty, const AsmAddress &address, const Immediate &imm);
732*03ce13f7SAndroid Build Coastguard Worker 
733*03ce13f7SAndroid Build Coastguard Worker   void Or(Type Ty, GPRRegister dst, GPRRegister src);
734*03ce13f7SAndroid Build Coastguard Worker   void Or(Type Ty, GPRRegister dst, const AsmAddress &address);
735*03ce13f7SAndroid Build Coastguard Worker   void Or(Type Ty, GPRRegister dst, const Immediate &imm);
736*03ce13f7SAndroid Build Coastguard Worker   void Or(Type Ty, const AsmAddress &address, GPRRegister reg);
737*03ce13f7SAndroid Build Coastguard Worker   void Or(Type Ty, const AsmAddress &address, const Immediate &imm);
738*03ce13f7SAndroid Build Coastguard Worker 
739*03ce13f7SAndroid Build Coastguard Worker   void Xor(Type Ty, GPRRegister dst, GPRRegister src);
740*03ce13f7SAndroid Build Coastguard Worker   void Xor(Type Ty, GPRRegister dst, const AsmAddress &address);
741*03ce13f7SAndroid Build Coastguard Worker   void Xor(Type Ty, GPRRegister dst, const Immediate &imm);
742*03ce13f7SAndroid Build Coastguard Worker   void Xor(Type Ty, const AsmAddress &address, GPRRegister reg);
743*03ce13f7SAndroid Build Coastguard Worker   void Xor(Type Ty, const AsmAddress &address, const Immediate &imm);
744*03ce13f7SAndroid Build Coastguard Worker 
745*03ce13f7SAndroid Build Coastguard Worker   void add(Type Ty, GPRRegister dst, GPRRegister src);
746*03ce13f7SAndroid Build Coastguard Worker   void add(Type Ty, GPRRegister reg, const AsmAddress &address);
747*03ce13f7SAndroid Build Coastguard Worker   void add(Type Ty, GPRRegister reg, const Immediate &imm);
748*03ce13f7SAndroid Build Coastguard Worker   void add(Type Ty, const AsmAddress &address, GPRRegister reg);
749*03ce13f7SAndroid Build Coastguard Worker   void add(Type Ty, const AsmAddress &address, const Immediate &imm);
750*03ce13f7SAndroid Build Coastguard Worker 
751*03ce13f7SAndroid Build Coastguard Worker   void adc(Type Ty, GPRRegister dst, GPRRegister src);
752*03ce13f7SAndroid Build Coastguard Worker   void adc(Type Ty, GPRRegister dst, const AsmAddress &address);
753*03ce13f7SAndroid Build Coastguard Worker   void adc(Type Ty, GPRRegister reg, const Immediate &imm);
754*03ce13f7SAndroid Build Coastguard Worker   void adc(Type Ty, const AsmAddress &address, GPRRegister reg);
755*03ce13f7SAndroid Build Coastguard Worker   void adc(Type Ty, const AsmAddress &address, const Immediate &imm);
756*03ce13f7SAndroid Build Coastguard Worker 
757*03ce13f7SAndroid Build Coastguard Worker   void sub(Type Ty, GPRRegister dst, GPRRegister src);
758*03ce13f7SAndroid Build Coastguard Worker   void sub(Type Ty, GPRRegister reg, const AsmAddress &address);
759*03ce13f7SAndroid Build Coastguard Worker   void sub(Type Ty, GPRRegister reg, const Immediate &imm);
760*03ce13f7SAndroid Build Coastguard Worker   void sub(Type Ty, const AsmAddress &address, GPRRegister reg);
761*03ce13f7SAndroid Build Coastguard Worker   void sub(Type Ty, const AsmAddress &address, const Immediate &imm);
762*03ce13f7SAndroid Build Coastguard Worker 
763*03ce13f7SAndroid Build Coastguard Worker   void sbb(Type Ty, GPRRegister dst, GPRRegister src);
764*03ce13f7SAndroid Build Coastguard Worker   void sbb(Type Ty, GPRRegister reg, const AsmAddress &address);
765*03ce13f7SAndroid Build Coastguard Worker   void sbb(Type Ty, GPRRegister reg, const Immediate &imm);
766*03ce13f7SAndroid Build Coastguard Worker   void sbb(Type Ty, const AsmAddress &address, GPRRegister reg);
767*03ce13f7SAndroid Build Coastguard Worker   void sbb(Type Ty, const AsmAddress &address, const Immediate &imm);
768*03ce13f7SAndroid Build Coastguard Worker 
769*03ce13f7SAndroid Build Coastguard Worker   void cbw();
770*03ce13f7SAndroid Build Coastguard Worker   void cwd();
771*03ce13f7SAndroid Build Coastguard Worker   void cdq();
772*03ce13f7SAndroid Build Coastguard Worker 
773*03ce13f7SAndroid Build Coastguard Worker   void div(Type Ty, GPRRegister reg);
774*03ce13f7SAndroid Build Coastguard Worker   void div(Type Ty, const AsmAddress &address);
775*03ce13f7SAndroid Build Coastguard Worker 
776*03ce13f7SAndroid Build Coastguard Worker   void idiv(Type Ty, GPRRegister reg);
777*03ce13f7SAndroid Build Coastguard Worker   void idiv(Type Ty, const AsmAddress &address);
778*03ce13f7SAndroid Build Coastguard Worker 
779*03ce13f7SAndroid Build Coastguard Worker   void imul(Type Ty, GPRRegister dst, GPRRegister src);
780*03ce13f7SAndroid Build Coastguard Worker   void imul(Type Ty, GPRRegister reg, const Immediate &imm);
781*03ce13f7SAndroid Build Coastguard Worker   void imul(Type Ty, GPRRegister reg, const AsmAddress &address);
782*03ce13f7SAndroid Build Coastguard Worker 
783*03ce13f7SAndroid Build Coastguard Worker   void imul(Type Ty, GPRRegister reg);
784*03ce13f7SAndroid Build Coastguard Worker   void imul(Type Ty, const AsmAddress &address);
785*03ce13f7SAndroid Build Coastguard Worker 
786*03ce13f7SAndroid Build Coastguard Worker   void imul(Type Ty, GPRRegister dst, GPRRegister src, const Immediate &imm);
787*03ce13f7SAndroid Build Coastguard Worker   void imul(Type Ty, GPRRegister dst, const AsmAddress &address,
788*03ce13f7SAndroid Build Coastguard Worker             const Immediate &imm);
789*03ce13f7SAndroid Build Coastguard Worker 
790*03ce13f7SAndroid Build Coastguard Worker   void mul(Type Ty, GPRRegister reg);
791*03ce13f7SAndroid Build Coastguard Worker   void mul(Type Ty, const AsmAddress &address);
792*03ce13f7SAndroid Build Coastguard Worker 
793*03ce13f7SAndroid Build Coastguard Worker   void incl(GPRRegister reg);
794*03ce13f7SAndroid Build Coastguard Worker   void incl(const AsmAddress &address);
795*03ce13f7SAndroid Build Coastguard Worker 
796*03ce13f7SAndroid Build Coastguard Worker   void decl(GPRRegister reg);
797*03ce13f7SAndroid Build Coastguard Worker   void decl(const AsmAddress &address);
798*03ce13f7SAndroid Build Coastguard Worker 
799*03ce13f7SAndroid Build Coastguard Worker   void rol(Type Ty, GPRRegister reg, const Immediate &imm);
800*03ce13f7SAndroid Build Coastguard Worker   void rol(Type Ty, GPRRegister operand, GPRRegister shifter);
801*03ce13f7SAndroid Build Coastguard Worker   void rol(Type Ty, const AsmAddress &operand, GPRRegister shifter);
802*03ce13f7SAndroid Build Coastguard Worker 
803*03ce13f7SAndroid Build Coastguard Worker   void shl(Type Ty, GPRRegister reg, const Immediate &imm);
804*03ce13f7SAndroid Build Coastguard Worker   void shl(Type Ty, GPRRegister operand, GPRRegister shifter);
805*03ce13f7SAndroid Build Coastguard Worker   void shl(Type Ty, const AsmAddress &operand, GPRRegister shifter);
806*03ce13f7SAndroid Build Coastguard Worker 
807*03ce13f7SAndroid Build Coastguard Worker   void shr(Type Ty, GPRRegister reg, const Immediate &imm);
808*03ce13f7SAndroid Build Coastguard Worker   void shr(Type Ty, GPRRegister operand, GPRRegister shifter);
809*03ce13f7SAndroid Build Coastguard Worker   void shr(Type Ty, const AsmAddress &operand, GPRRegister shifter);
810*03ce13f7SAndroid Build Coastguard Worker 
811*03ce13f7SAndroid Build Coastguard Worker   void sar(Type Ty, GPRRegister reg, const Immediate &imm);
812*03ce13f7SAndroid Build Coastguard Worker   void sar(Type Ty, GPRRegister operand, GPRRegister shifter);
813*03ce13f7SAndroid Build Coastguard Worker   void sar(Type Ty, const AsmAddress &address, GPRRegister shifter);
814*03ce13f7SAndroid Build Coastguard Worker 
815*03ce13f7SAndroid Build Coastguard Worker   void shld(Type Ty, GPRRegister dst, GPRRegister src);
816*03ce13f7SAndroid Build Coastguard Worker   void shld(Type Ty, GPRRegister dst, GPRRegister src, const Immediate &imm);
817*03ce13f7SAndroid Build Coastguard Worker   void shld(Type Ty, const AsmAddress &operand, GPRRegister src);
818*03ce13f7SAndroid Build Coastguard Worker   void shrd(Type Ty, GPRRegister dst, GPRRegister src);
819*03ce13f7SAndroid Build Coastguard Worker   void shrd(Type Ty, GPRRegister dst, GPRRegister src, const Immediate &imm);
820*03ce13f7SAndroid Build Coastguard Worker   void shrd(Type Ty, const AsmAddress &dst, GPRRegister src);
821*03ce13f7SAndroid Build Coastguard Worker 
822*03ce13f7SAndroid Build Coastguard Worker   void neg(Type Ty, GPRRegister reg);
823*03ce13f7SAndroid Build Coastguard Worker   void neg(Type Ty, const AsmAddress &addr);
824*03ce13f7SAndroid Build Coastguard Worker   void notl(GPRRegister reg);
825*03ce13f7SAndroid Build Coastguard Worker 
826*03ce13f7SAndroid Build Coastguard Worker   void bsf(Type Ty, GPRRegister dst, GPRRegister src);
827*03ce13f7SAndroid Build Coastguard Worker   void bsf(Type Ty, GPRRegister dst, const AsmAddress &src);
828*03ce13f7SAndroid Build Coastguard Worker   void bsr(Type Ty, GPRRegister dst, GPRRegister src);
829*03ce13f7SAndroid Build Coastguard Worker   void bsr(Type Ty, GPRRegister dst, const AsmAddress &src);
830*03ce13f7SAndroid Build Coastguard Worker 
831*03ce13f7SAndroid Build Coastguard Worker   void bswap(Type Ty, GPRRegister reg);
832*03ce13f7SAndroid Build Coastguard Worker 
833*03ce13f7SAndroid Build Coastguard Worker   void bt(GPRRegister base, GPRRegister offset);
834*03ce13f7SAndroid Build Coastguard Worker 
835*03ce13f7SAndroid Build Coastguard Worker   void ret();
836*03ce13f7SAndroid Build Coastguard Worker   void ret(const Immediate &imm);
837*03ce13f7SAndroid Build Coastguard Worker 
838*03ce13f7SAndroid Build Coastguard Worker   // 'size' indicates size in bytes and must be in the range 1..8.
839*03ce13f7SAndroid Build Coastguard Worker   void nop(int size = 1);
840*03ce13f7SAndroid Build Coastguard Worker   void int3();
841*03ce13f7SAndroid Build Coastguard Worker   void hlt();
842*03ce13f7SAndroid Build Coastguard Worker   void ud2();
843*03ce13f7SAndroid Build Coastguard Worker 
844*03ce13f7SAndroid Build Coastguard Worker   // j(Label) is fully tested.
845*03ce13f7SAndroid Build Coastguard Worker   void j(BrCond condition, Label *label, bool near = kFarJump);
846*03ce13f7SAndroid Build Coastguard Worker   void j(BrCond condition, const ConstantRelocatable *label); // not testable.
847*03ce13f7SAndroid Build Coastguard Worker 
848*03ce13f7SAndroid Build Coastguard Worker   void jmp(GPRRegister reg);
849*03ce13f7SAndroid Build Coastguard Worker   void jmp(Label *label, bool near = kFarJump);
850*03ce13f7SAndroid Build Coastguard Worker   void jmp(const ConstantRelocatable *label); // not testable.
851*03ce13f7SAndroid Build Coastguard Worker   void jmp(const Immediate &abs_address);
852*03ce13f7SAndroid Build Coastguard Worker 
853*03ce13f7SAndroid Build Coastguard Worker   void mfence();
854*03ce13f7SAndroid Build Coastguard Worker 
855*03ce13f7SAndroid Build Coastguard Worker   void lock();
856*03ce13f7SAndroid Build Coastguard Worker   void cmpxchg(Type Ty, const AsmAddress &address, GPRRegister reg,
857*03ce13f7SAndroid Build Coastguard Worker                bool Locked);
858*03ce13f7SAndroid Build Coastguard Worker   void cmpxchg8b(const AsmAddress &address, bool Locked);
859*03ce13f7SAndroid Build Coastguard Worker   void xadd(Type Ty, const AsmAddress &address, GPRRegister reg, bool Locked);
860*03ce13f7SAndroid Build Coastguard Worker   void xchg(Type Ty, GPRRegister reg0, GPRRegister reg1);
861*03ce13f7SAndroid Build Coastguard Worker   void xchg(Type Ty, const AsmAddress &address, GPRRegister reg);
862*03ce13f7SAndroid Build Coastguard Worker 
863*03ce13f7SAndroid Build Coastguard Worker   /// \name Intel Architecture Code Analyzer markers.
864*03ce13f7SAndroid Build Coastguard Worker   /// @{
865*03ce13f7SAndroid Build Coastguard Worker   void iaca_start();
866*03ce13f7SAndroid Build Coastguard Worker   void iaca_end();
867*03ce13f7SAndroid Build Coastguard Worker   /// @}
868*03ce13f7SAndroid Build Coastguard Worker 
869*03ce13f7SAndroid Build Coastguard Worker   void emitSegmentOverride(uint8_t prefix);
870*03ce13f7SAndroid Build Coastguard Worker 
preferredLoopAlignment()871*03ce13f7SAndroid Build Coastguard Worker   intptr_t preferredLoopAlignment() { return 16; }
872*03ce13f7SAndroid Build Coastguard Worker   void align(intptr_t alignment, intptr_t offset);
873*03ce13f7SAndroid Build Coastguard Worker   void bind(Label *label);
874*03ce13f7SAndroid Build Coastguard Worker 
CodeSize()875*03ce13f7SAndroid Build Coastguard Worker   intptr_t CodeSize() const { return Buffer.size(); }
876*03ce13f7SAndroid Build Coastguard Worker 
877*03ce13f7SAndroid Build Coastguard Worker protected:
878*03ce13f7SAndroid Build Coastguard Worker   inline void emitUint8(uint8_t value);
879*03ce13f7SAndroid Build Coastguard Worker 
880*03ce13f7SAndroid Build Coastguard Worker private:
881*03ce13f7SAndroid Build Coastguard Worker   ENABLE_MAKE_UNIQUE;
882*03ce13f7SAndroid Build Coastguard Worker 
883*03ce13f7SAndroid Build Coastguard Worker   static constexpr Type RexTypeIrrelevant = IceType_i32;
884*03ce13f7SAndroid Build Coastguard Worker   static constexpr Type RexTypeForceRexW = IceType_i64;
885*03ce13f7SAndroid Build Coastguard Worker   static constexpr GPRRegister RexRegIrrelevant = GPRRegister::Encoded_Reg_eax;
886*03ce13f7SAndroid Build Coastguard Worker 
887*03ce13f7SAndroid Build Coastguard Worker   inline void emitInt16(int16_t value);
888*03ce13f7SAndroid Build Coastguard Worker   inline void emitInt32(int32_t value);
889*03ce13f7SAndroid Build Coastguard Worker   inline void emitRegisterOperand(int rm, int reg);
890*03ce13f7SAndroid Build Coastguard Worker   template <typename RegType, typename RmType>
891*03ce13f7SAndroid Build Coastguard Worker   inline void emitXmmRegisterOperand(RegType reg, RmType rm);
892*03ce13f7SAndroid Build Coastguard Worker   inline void emitOperandSizeOverride();
893*03ce13f7SAndroid Build Coastguard Worker 
894*03ce13f7SAndroid Build Coastguard Worker   void emitOperand(int rm, const AsmOperand &operand, RelocOffsetT Addend = 0);
895*03ce13f7SAndroid Build Coastguard Worker   void emitImmediate(Type ty, const Immediate &imm);
896*03ce13f7SAndroid Build Coastguard Worker   void emitComplexI8(int rm, const AsmOperand &operand,
897*03ce13f7SAndroid Build Coastguard Worker                      const Immediate &immediate);
898*03ce13f7SAndroid Build Coastguard Worker   void emitComplex(Type Ty, int rm, const AsmOperand &operand,
899*03ce13f7SAndroid Build Coastguard Worker                    const Immediate &immediate);
900*03ce13f7SAndroid Build Coastguard Worker   void emitLabel(Label *label, intptr_t instruction_size);
901*03ce13f7SAndroid Build Coastguard Worker   void emitLabelLink(Label *label);
902*03ce13f7SAndroid Build Coastguard Worker   void emitNearLabelLink(Label *label);
903*03ce13f7SAndroid Build Coastguard Worker 
904*03ce13f7SAndroid Build Coastguard Worker   void emitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm);
905*03ce13f7SAndroid Build Coastguard Worker   void emitGenericShift(int rm, Type Ty, const AsmOperand &operand,
906*03ce13f7SAndroid Build Coastguard Worker                         GPRRegister shifter);
907*03ce13f7SAndroid Build Coastguard Worker 
908*03ce13f7SAndroid Build Coastguard Worker   using LabelVector = std::vector<Label *>;
909*03ce13f7SAndroid Build Coastguard Worker   // A vector of pool-allocated x86 labels for CFG nodes.
910*03ce13f7SAndroid Build Coastguard Worker   LabelVector CfgNodeLabels;
911*03ce13f7SAndroid Build Coastguard Worker   // A vector of pool-allocated x86 labels for Local labels.
912*03ce13f7SAndroid Build Coastguard Worker   LabelVector LocalLabels;
913*03ce13f7SAndroid Build Coastguard Worker 
914*03ce13f7SAndroid Build Coastguard Worker   Label *getOrCreateLabel(SizeT Number, LabelVector &Labels);
915*03ce13f7SAndroid Build Coastguard Worker 
916*03ce13f7SAndroid Build Coastguard Worker   // The arith_int() methods factor out the commonality between the encodings
917*03ce13f7SAndroid Build Coastguard Worker   // of add(), Or(), adc(), sbb(), And(), sub(), Xor(), and cmp(). The Tag
918*03ce13f7SAndroid Build Coastguard Worker   // parameter is statically asserted to be less than 8.
919*03ce13f7SAndroid Build Coastguard Worker   template <uint32_t Tag>
920*03ce13f7SAndroid Build Coastguard Worker   void arith_int(Type Ty, GPRRegister reg, const Immediate &imm);
921*03ce13f7SAndroid Build Coastguard Worker 
922*03ce13f7SAndroid Build Coastguard Worker   template <uint32_t Tag>
923*03ce13f7SAndroid Build Coastguard Worker   void arith_int(Type Ty, GPRRegister reg0, GPRRegister reg1);
924*03ce13f7SAndroid Build Coastguard Worker 
925*03ce13f7SAndroid Build Coastguard Worker   template <uint32_t Tag>
926*03ce13f7SAndroid Build Coastguard Worker   void arith_int(Type Ty, GPRRegister reg, const AsmAddress &address);
927*03ce13f7SAndroid Build Coastguard Worker 
928*03ce13f7SAndroid Build Coastguard Worker   template <uint32_t Tag>
929*03ce13f7SAndroid Build Coastguard Worker   void arith_int(Type Ty, const AsmAddress &address, GPRRegister reg);
930*03ce13f7SAndroid Build Coastguard Worker 
931*03ce13f7SAndroid Build Coastguard Worker   template <uint32_t Tag>
932*03ce13f7SAndroid Build Coastguard Worker   void arith_int(Type Ty, const AsmAddress &address, const Immediate &imm);
933*03ce13f7SAndroid Build Coastguard Worker 
934*03ce13f7SAndroid Build Coastguard Worker   // gprEncoding returns Reg encoding for operand emission.
gprEncoding(const RegType Reg)935*03ce13f7SAndroid Build Coastguard Worker   template <typename RegType> GPRRegister gprEncoding(const RegType Reg) {
936*03ce13f7SAndroid Build Coastguard Worker     return static_cast<GPRRegister>(Reg);
937*03ce13f7SAndroid Build Coastguard Worker   }
938*03ce13f7SAndroid Build Coastguard Worker };
939*03ce13f7SAndroid Build Coastguard Worker 
emitUint8(uint8_t value)940*03ce13f7SAndroid Build Coastguard Worker inline void AssemblerX8632::emitUint8(uint8_t value) {
941*03ce13f7SAndroid Build Coastguard Worker   Buffer.emit<uint8_t>(value);
942*03ce13f7SAndroid Build Coastguard Worker }
943*03ce13f7SAndroid Build Coastguard Worker 
emitInt16(int16_t value)944*03ce13f7SAndroid Build Coastguard Worker inline void AssemblerX8632::emitInt16(int16_t value) {
945*03ce13f7SAndroid Build Coastguard Worker   Buffer.emit<int16_t>(value);
946*03ce13f7SAndroid Build Coastguard Worker }
947*03ce13f7SAndroid Build Coastguard Worker 
emitInt32(int32_t value)948*03ce13f7SAndroid Build Coastguard Worker inline void AssemblerX8632::emitInt32(int32_t value) {
949*03ce13f7SAndroid Build Coastguard Worker   Buffer.emit<int32_t>(value);
950*03ce13f7SAndroid Build Coastguard Worker }
951*03ce13f7SAndroid Build Coastguard Worker 
emitRegisterOperand(int reg,int rm)952*03ce13f7SAndroid Build Coastguard Worker inline void AssemblerX8632::emitRegisterOperand(int reg, int rm) {
953*03ce13f7SAndroid Build Coastguard Worker   assert(reg >= 0 && reg < 8);
954*03ce13f7SAndroid Build Coastguard Worker   assert(rm >= 0 && rm < 8);
955*03ce13f7SAndroid Build Coastguard Worker   Buffer.emit<uint8_t>(0xC0 + (reg << 3) + rm);
956*03ce13f7SAndroid Build Coastguard Worker }
957*03ce13f7SAndroid Build Coastguard Worker 
958*03ce13f7SAndroid Build Coastguard Worker template <typename RegType, typename RmType>
emitXmmRegisterOperand(RegType reg,RmType rm)959*03ce13f7SAndroid Build Coastguard Worker inline void AssemblerX8632::emitXmmRegisterOperand(RegType reg, RmType rm) {
960*03ce13f7SAndroid Build Coastguard Worker   emitRegisterOperand(gprEncoding(reg), gprEncoding(rm));
961*03ce13f7SAndroid Build Coastguard Worker }
962*03ce13f7SAndroid Build Coastguard Worker 
emitOperandSizeOverride()963*03ce13f7SAndroid Build Coastguard Worker inline void AssemblerX8632::emitOperandSizeOverride() { emitUint8(0x66); }
964*03ce13f7SAndroid Build Coastguard Worker 
965*03ce13f7SAndroid Build Coastguard Worker using Label = AssemblerX8632::Label;
966*03ce13f7SAndroid Build Coastguard Worker using Immediate = AssemblerX8632::Immediate;
967*03ce13f7SAndroid Build Coastguard Worker 
968*03ce13f7SAndroid Build Coastguard Worker } // end of namespace X8632
969*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
970*03ce13f7SAndroid Build Coastguard Worker 
971*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICEASSEMBLERX8632_H
972