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