xref: /aosp_15_r20/art/compiler/optimizing/code_generator_x86.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "arch/x86/instruction_set_features_x86.h"
21*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
22*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
23*795d594fSAndroid Build Coastguard Worker #include "code_generator.h"
24*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_types.h"
25*795d594fSAndroid Build Coastguard Worker #include "driver/compiler_options.h"
26*795d594fSAndroid Build Coastguard Worker #include "nodes.h"
27*795d594fSAndroid Build Coastguard Worker #include "parallel_move_resolver.h"
28*795d594fSAndroid Build Coastguard Worker #include "utils/x86/assembler_x86.h"
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
31*795d594fSAndroid Build Coastguard Worker namespace x86 {
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker // Use a local definition to prevent copying mistakes.
34*795d594fSAndroid Build Coastguard Worker static constexpr size_t kX86WordSize = static_cast<size_t>(kX86PointerSize);
35*795d594fSAndroid Build Coastguard Worker 
36*795d594fSAndroid Build Coastguard Worker class CodeGeneratorX86;
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
39*795d594fSAndroid Build Coastguard Worker static constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX };
40*795d594fSAndroid Build Coastguard Worker static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
41*795d594fSAndroid Build Coastguard Worker static constexpr XmmRegister kParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 };
42*795d594fSAndroid Build Coastguard Worker static constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters);
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX, EBX };
45*795d594fSAndroid Build Coastguard Worker static constexpr size_t kRuntimeParameterCoreRegistersLength =
46*795d594fSAndroid Build Coastguard Worker     arraysize(kRuntimeParameterCoreRegisters);
47*795d594fSAndroid Build Coastguard Worker static constexpr XmmRegister kRuntimeParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 };
48*795d594fSAndroid Build Coastguard Worker static constexpr size_t kRuntimeParameterFpuRegistersLength =
49*795d594fSAndroid Build Coastguard Worker     arraysize(kRuntimeParameterFpuRegisters);
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker #define UNIMPLEMENTED_INTRINSIC_LIST_X86(V) \
52*795d594fSAndroid Build Coastguard Worker   V(MathSignumFloat)                        \
53*795d594fSAndroid Build Coastguard Worker   V(MathSignumDouble)                       \
54*795d594fSAndroid Build Coastguard Worker   V(MathCopySignFloat)                      \
55*795d594fSAndroid Build Coastguard Worker   V(MathCopySignDouble)                     \
56*795d594fSAndroid Build Coastguard Worker   V(MathRoundDouble)                        \
57*795d594fSAndroid Build Coastguard Worker   V(FloatIsInfinite)                        \
58*795d594fSAndroid Build Coastguard Worker   V(DoubleIsInfinite)                       \
59*795d594fSAndroid Build Coastguard Worker   V(IntegerHighestOneBit)                   \
60*795d594fSAndroid Build Coastguard Worker   V(LongHighestOneBit)                      \
61*795d594fSAndroid Build Coastguard Worker   V(LongDivideUnsigned)                     \
62*795d594fSAndroid Build Coastguard Worker   V(IntegerRemainderUnsigned)               \
63*795d594fSAndroid Build Coastguard Worker   V(LongRemainderUnsigned)                  \
64*795d594fSAndroid Build Coastguard Worker   V(CRC32Update)                            \
65*795d594fSAndroid Build Coastguard Worker   V(CRC32UpdateBytes)                       \
66*795d594fSAndroid Build Coastguard Worker   V(CRC32UpdateByteBuffer)                  \
67*795d594fSAndroid Build Coastguard Worker   V(FP16ToFloat)                            \
68*795d594fSAndroid Build Coastguard Worker   V(FP16ToHalf)                             \
69*795d594fSAndroid Build Coastguard Worker   V(FP16Floor)                              \
70*795d594fSAndroid Build Coastguard Worker   V(FP16Ceil)                               \
71*795d594fSAndroid Build Coastguard Worker   V(FP16Rint)                               \
72*795d594fSAndroid Build Coastguard Worker   V(FP16Greater)                            \
73*795d594fSAndroid Build Coastguard Worker   V(FP16GreaterEquals)                      \
74*795d594fSAndroid Build Coastguard Worker   V(FP16Less)                               \
75*795d594fSAndroid Build Coastguard Worker   V(FP16LessEquals)                         \
76*795d594fSAndroid Build Coastguard Worker   V(FP16Compare)                            \
77*795d594fSAndroid Build Coastguard Worker   V(FP16Min)                                \
78*795d594fSAndroid Build Coastguard Worker   V(FP16Max)                                \
79*795d594fSAndroid Build Coastguard Worker   V(MathMultiplyHigh)                       \
80*795d594fSAndroid Build Coastguard Worker   V(StringStringIndexOf)                    \
81*795d594fSAndroid Build Coastguard Worker   V(StringStringIndexOfAfter)               \
82*795d594fSAndroid Build Coastguard Worker   V(StringBufferAppend)                     \
83*795d594fSAndroid Build Coastguard Worker   V(StringBufferLength)                     \
84*795d594fSAndroid Build Coastguard Worker   V(StringBufferToString)                   \
85*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendObject)              \
86*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendString)              \
87*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendCharSequence)        \
88*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendCharArray)           \
89*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendBoolean)             \
90*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendChar)                \
91*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendInt)                 \
92*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendLong)                \
93*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendFloat)               \
94*795d594fSAndroid Build Coastguard Worker   V(StringBuilderAppendDouble)              \
95*795d594fSAndroid Build Coastguard Worker   V(StringBuilderLength)                    \
96*795d594fSAndroid Build Coastguard Worker   V(StringBuilderToString)                  \
97*795d594fSAndroid Build Coastguard Worker   V(UnsafeArrayBaseOffset)                  \
98*795d594fSAndroid Build Coastguard Worker   /* 1.8 */                                 \
99*795d594fSAndroid Build Coastguard Worker   V(MethodHandleInvokeExact)                \
100*795d594fSAndroid Build Coastguard Worker   V(MethodHandleInvoke)                     \
101*795d594fSAndroid Build Coastguard Worker   /* OpenJDK 11 */                          \
102*795d594fSAndroid Build Coastguard Worker   V(JdkUnsafeArrayBaseOffset)
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker class InvokeRuntimeCallingConvention : public CallingConvention<Register, XmmRegister> {
105*795d594fSAndroid Build Coastguard Worker  public:
InvokeRuntimeCallingConvention()106*795d594fSAndroid Build Coastguard Worker   InvokeRuntimeCallingConvention()
107*795d594fSAndroid Build Coastguard Worker       : CallingConvention(kRuntimeParameterCoreRegisters,
108*795d594fSAndroid Build Coastguard Worker                           kRuntimeParameterCoreRegistersLength,
109*795d594fSAndroid Build Coastguard Worker                           kRuntimeParameterFpuRegisters,
110*795d594fSAndroid Build Coastguard Worker                           kRuntimeParameterFpuRegistersLength,
111*795d594fSAndroid Build Coastguard Worker                           kX86PointerSize) {}
112*795d594fSAndroid Build Coastguard Worker 
113*795d594fSAndroid Build Coastguard Worker  private:
114*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
115*795d594fSAndroid Build Coastguard Worker };
116*795d594fSAndroid Build Coastguard Worker 
117*795d594fSAndroid Build Coastguard Worker class InvokeDexCallingConvention : public CallingConvention<Register, XmmRegister> {
118*795d594fSAndroid Build Coastguard Worker  public:
InvokeDexCallingConvention()119*795d594fSAndroid Build Coastguard Worker   InvokeDexCallingConvention() : CallingConvention(
120*795d594fSAndroid Build Coastguard Worker       kParameterCoreRegisters,
121*795d594fSAndroid Build Coastguard Worker       kParameterCoreRegistersLength,
122*795d594fSAndroid Build Coastguard Worker       kParameterFpuRegisters,
123*795d594fSAndroid Build Coastguard Worker       kParameterFpuRegistersLength,
124*795d594fSAndroid Build Coastguard Worker       kX86PointerSize) {}
125*795d594fSAndroid Build Coastguard Worker 
GetRegisterPairAt(size_t argument_index)126*795d594fSAndroid Build Coastguard Worker   RegisterPair GetRegisterPairAt(size_t argument_index) {
127*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
128*795d594fSAndroid Build Coastguard Worker     return kParameterCorePairRegisters[argument_index];
129*795d594fSAndroid Build Coastguard Worker   }
130*795d594fSAndroid Build Coastguard Worker 
131*795d594fSAndroid Build Coastguard Worker  private:
132*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
133*795d594fSAndroid Build Coastguard Worker };
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker class InvokeDexCallingConventionVisitorX86 : public InvokeDexCallingConventionVisitor {
136*795d594fSAndroid Build Coastguard Worker  public:
InvokeDexCallingConventionVisitorX86()137*795d594fSAndroid Build Coastguard Worker   InvokeDexCallingConventionVisitorX86() {}
~InvokeDexCallingConventionVisitorX86()138*795d594fSAndroid Build Coastguard Worker   virtual ~InvokeDexCallingConventionVisitorX86() {}
139*795d594fSAndroid Build Coastguard Worker 
140*795d594fSAndroid Build Coastguard Worker   Location GetNextLocation(DataType::Type type) override;
141*795d594fSAndroid Build Coastguard Worker   Location GetReturnLocation(DataType::Type type) const override;
142*795d594fSAndroid Build Coastguard Worker   Location GetMethodLocation() const override;
143*795d594fSAndroid Build Coastguard Worker 
144*795d594fSAndroid Build Coastguard Worker  private:
145*795d594fSAndroid Build Coastguard Worker   InvokeDexCallingConvention calling_convention;
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorX86);
148*795d594fSAndroid Build Coastguard Worker };
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker class CriticalNativeCallingConventionVisitorX86 : public InvokeDexCallingConventionVisitor {
151*795d594fSAndroid Build Coastguard Worker  public:
CriticalNativeCallingConventionVisitorX86(bool for_register_allocation)152*795d594fSAndroid Build Coastguard Worker   explicit CriticalNativeCallingConventionVisitorX86(bool for_register_allocation)
153*795d594fSAndroid Build Coastguard Worker       : for_register_allocation_(for_register_allocation) {}
154*795d594fSAndroid Build Coastguard Worker 
~CriticalNativeCallingConventionVisitorX86()155*795d594fSAndroid Build Coastguard Worker   virtual ~CriticalNativeCallingConventionVisitorX86() {}
156*795d594fSAndroid Build Coastguard Worker 
157*795d594fSAndroid Build Coastguard Worker   Location GetNextLocation(DataType::Type type) override;
158*795d594fSAndroid Build Coastguard Worker   Location GetReturnLocation(DataType::Type type) const override;
159*795d594fSAndroid Build Coastguard Worker   Location GetMethodLocation() const override;
160*795d594fSAndroid Build Coastguard Worker 
GetStackOffset()161*795d594fSAndroid Build Coastguard Worker   size_t GetStackOffset() const { return stack_offset_; }
162*795d594fSAndroid Build Coastguard Worker 
163*795d594fSAndroid Build Coastguard Worker  private:
164*795d594fSAndroid Build Coastguard Worker   // Register allocator does not support adjusting frame size, so we cannot provide final locations
165*795d594fSAndroid Build Coastguard Worker   // of stack arguments for register allocation. We ask the register allocator for any location and
166*795d594fSAndroid Build Coastguard Worker   // move these arguments to the right place after adjusting the SP when generating the call.
167*795d594fSAndroid Build Coastguard Worker   const bool for_register_allocation_;
168*795d594fSAndroid Build Coastguard Worker   size_t stack_offset_ = 0u;
169*795d594fSAndroid Build Coastguard Worker 
170*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(CriticalNativeCallingConventionVisitorX86);
171*795d594fSAndroid Build Coastguard Worker };
172*795d594fSAndroid Build Coastguard Worker 
173*795d594fSAndroid Build Coastguard Worker class FieldAccessCallingConventionX86 : public FieldAccessCallingConvention {
174*795d594fSAndroid Build Coastguard Worker  public:
FieldAccessCallingConventionX86()175*795d594fSAndroid Build Coastguard Worker   FieldAccessCallingConventionX86() {}
176*795d594fSAndroid Build Coastguard Worker 
GetObjectLocation()177*795d594fSAndroid Build Coastguard Worker   Location GetObjectLocation() const override {
178*795d594fSAndroid Build Coastguard Worker     return Location::RegisterLocation(ECX);
179*795d594fSAndroid Build Coastguard Worker   }
GetFieldIndexLocation()180*795d594fSAndroid Build Coastguard Worker   Location GetFieldIndexLocation() const override {
181*795d594fSAndroid Build Coastguard Worker     return Location::RegisterLocation(EAX);
182*795d594fSAndroid Build Coastguard Worker   }
GetReturnLocation(DataType::Type type)183*795d594fSAndroid Build Coastguard Worker   Location GetReturnLocation(DataType::Type type) const override {
184*795d594fSAndroid Build Coastguard Worker     return DataType::Is64BitType(type)
185*795d594fSAndroid Build Coastguard Worker         ? Location::RegisterPairLocation(EAX, EDX)
186*795d594fSAndroid Build Coastguard Worker         : Location::RegisterLocation(EAX);
187*795d594fSAndroid Build Coastguard Worker   }
GetSetValueLocation(DataType::Type type,bool is_instance)188*795d594fSAndroid Build Coastguard Worker   Location GetSetValueLocation(DataType::Type type, bool is_instance) const override {
189*795d594fSAndroid Build Coastguard Worker     return DataType::Is64BitType(type)
190*795d594fSAndroid Build Coastguard Worker         ? (is_instance
191*795d594fSAndroid Build Coastguard Worker             ? Location::RegisterPairLocation(EDX, EBX)
192*795d594fSAndroid Build Coastguard Worker             : Location::RegisterPairLocation(ECX, EDX))
193*795d594fSAndroid Build Coastguard Worker         : (is_instance
194*795d594fSAndroid Build Coastguard Worker             ? Location::RegisterLocation(EDX)
195*795d594fSAndroid Build Coastguard Worker             : Location::RegisterLocation(ECX));
196*795d594fSAndroid Build Coastguard Worker   }
GetFpuLocation(DataType::Type type)197*795d594fSAndroid Build Coastguard Worker   Location GetFpuLocation([[maybe_unused]] DataType::Type type) const override {
198*795d594fSAndroid Build Coastguard Worker     return Location::FpuRegisterLocation(XMM0);
199*795d594fSAndroid Build Coastguard Worker   }
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker  private:
202*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionX86);
203*795d594fSAndroid Build Coastguard Worker };
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker class ParallelMoveResolverX86 : public ParallelMoveResolverWithSwap {
206*795d594fSAndroid Build Coastguard Worker  public:
ParallelMoveResolverX86(ArenaAllocator * allocator,CodeGeneratorX86 * codegen)207*795d594fSAndroid Build Coastguard Worker   ParallelMoveResolverX86(ArenaAllocator* allocator, CodeGeneratorX86* codegen)
208*795d594fSAndroid Build Coastguard Worker       : ParallelMoveResolverWithSwap(allocator), codegen_(codegen) {}
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker   void EmitMove(size_t index) override;
211*795d594fSAndroid Build Coastguard Worker   void EmitSwap(size_t index) override;
212*795d594fSAndroid Build Coastguard Worker   void SpillScratch(int reg) override;
213*795d594fSAndroid Build Coastguard Worker   void RestoreScratch(int reg) override;
214*795d594fSAndroid Build Coastguard Worker 
215*795d594fSAndroid Build Coastguard Worker   X86Assembler* GetAssembler() const;
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker  private:
218*795d594fSAndroid Build Coastguard Worker   void Exchange(Register reg, int mem);
219*795d594fSAndroid Build Coastguard Worker   void Exchange32(XmmRegister reg, int mem);
220*795d594fSAndroid Build Coastguard Worker   void Exchange128(XmmRegister reg, int mem);
221*795d594fSAndroid Build Coastguard Worker   void ExchangeMemory(int mem1, int mem2, int number_of_words);
222*795d594fSAndroid Build Coastguard Worker   void MoveMemoryToMemory(int dst, int src, int number_of_words);
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker   CodeGeneratorX86* const codegen_;
225*795d594fSAndroid Build Coastguard Worker 
226*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverX86);
227*795d594fSAndroid Build Coastguard Worker };
228*795d594fSAndroid Build Coastguard Worker 
229*795d594fSAndroid Build Coastguard Worker class LocationsBuilderX86 : public HGraphVisitor {
230*795d594fSAndroid Build Coastguard Worker  public:
LocationsBuilderX86(HGraph * graph,CodeGeneratorX86 * codegen)231*795d594fSAndroid Build Coastguard Worker   LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen)
232*795d594fSAndroid Build Coastguard Worker       : HGraphVisitor(graph), codegen_(codegen) {}
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker #define DECLARE_VISIT_INSTRUCTION(name, super)     \
235*795d594fSAndroid Build Coastguard Worker   void Visit##name(H##name* instr) override;
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker   FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION)238*795d594fSAndroid Build Coastguard Worker   FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION)
239*795d594fSAndroid Build Coastguard Worker   FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(DECLARE_VISIT_INSTRUCTION)
240*795d594fSAndroid Build Coastguard Worker 
241*795d594fSAndroid Build Coastguard Worker #undef DECLARE_VISIT_INSTRUCTION
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker   void VisitInstruction(HInstruction* instruction) override {
244*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
245*795d594fSAndroid Build Coastguard Worker                << " (id " << instruction->GetId() << ")";
246*795d594fSAndroid Build Coastguard Worker   }
247*795d594fSAndroid Build Coastguard Worker 
248*795d594fSAndroid Build Coastguard Worker  private:
249*795d594fSAndroid Build Coastguard Worker   void HandleBitwiseOperation(HBinaryOperation* instruction);
250*795d594fSAndroid Build Coastguard Worker   void HandleInvoke(HInvoke* invoke);
251*795d594fSAndroid Build Coastguard Worker   void HandleCondition(HCondition* condition);
252*795d594fSAndroid Build Coastguard Worker   void HandleRotate(HBinaryOperation* rotate);
253*795d594fSAndroid Build Coastguard Worker   void HandleShift(HBinaryOperation* instruction);
254*795d594fSAndroid Build Coastguard Worker   void HandleFieldSet(HInstruction* instruction,
255*795d594fSAndroid Build Coastguard Worker                       const FieldInfo& field_info,
256*795d594fSAndroid Build Coastguard Worker                       WriteBarrierKind write_barrier_kind);
257*795d594fSAndroid Build Coastguard Worker   void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
258*795d594fSAndroid Build Coastguard Worker   bool CpuHasAvxFeatureFlag();
259*795d594fSAndroid Build Coastguard Worker   bool CpuHasAvx2FeatureFlag();
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker   CodeGeneratorX86* const codegen_;
262*795d594fSAndroid Build Coastguard Worker   InvokeDexCallingConventionVisitorX86 parameter_visitor_;
263*795d594fSAndroid Build Coastguard Worker 
264*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86);
265*795d594fSAndroid Build Coastguard Worker };
266*795d594fSAndroid Build Coastguard Worker 
267*795d594fSAndroid Build Coastguard Worker class InstructionCodeGeneratorX86 : public InstructionCodeGenerator {
268*795d594fSAndroid Build Coastguard Worker  public:
269*795d594fSAndroid Build Coastguard Worker   InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen);
270*795d594fSAndroid Build Coastguard Worker 
271*795d594fSAndroid Build Coastguard Worker #define DECLARE_VISIT_INSTRUCTION(name, super)     \
272*795d594fSAndroid Build Coastguard Worker   void Visit##name(H##name* instr) override;
273*795d594fSAndroid Build Coastguard Worker 
274*795d594fSAndroid Build Coastguard Worker   FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION)275*795d594fSAndroid Build Coastguard Worker   FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION)
276*795d594fSAndroid Build Coastguard Worker   FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(DECLARE_VISIT_INSTRUCTION)
277*795d594fSAndroid Build Coastguard Worker 
278*795d594fSAndroid Build Coastguard Worker #undef DECLARE_VISIT_INSTRUCTION
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker   void VisitInstruction(HInstruction* instruction) override {
281*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
282*795d594fSAndroid Build Coastguard Worker                << " (id " << instruction->GetId() << ")";
283*795d594fSAndroid Build Coastguard Worker   }
284*795d594fSAndroid Build Coastguard Worker 
GetAssembler()285*795d594fSAndroid Build Coastguard Worker   X86Assembler* GetAssembler() const { return assembler_; }
286*795d594fSAndroid Build Coastguard Worker 
287*795d594fSAndroid Build Coastguard Worker   // The compare/jump sequence will generate about (1.5 * num_entries) instructions. A jump
288*795d594fSAndroid Build Coastguard Worker   // table version generates 7 instructions and num_entries literals. Compare/jump sequence will
289*795d594fSAndroid Build Coastguard Worker   // generates less code/data with a small num_entries.
290*795d594fSAndroid Build Coastguard Worker   static constexpr uint32_t kPackedSwitchJumpTableThreshold = 5;
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker   // Generate a GC root reference load:
293*795d594fSAndroid Build Coastguard Worker   //
294*795d594fSAndroid Build Coastguard Worker   //   root <- *address
295*795d594fSAndroid Build Coastguard Worker   //
296*795d594fSAndroid Build Coastguard Worker   // while honoring read barriers based on read_barrier_option.
297*795d594fSAndroid Build Coastguard Worker   void GenerateGcRootFieldLoad(HInstruction* instruction,
298*795d594fSAndroid Build Coastguard Worker                                Location root,
299*795d594fSAndroid Build Coastguard Worker                                const Address& address,
300*795d594fSAndroid Build Coastguard Worker                                Label* fixup_label,
301*795d594fSAndroid Build Coastguard Worker                                ReadBarrierOption read_barrier_option);
302*795d594fSAndroid Build Coastguard Worker 
303*795d594fSAndroid Build Coastguard Worker   void HandleFieldSet(HInstruction* instruction,
304*795d594fSAndroid Build Coastguard Worker                       uint32_t value_index,
305*795d594fSAndroid Build Coastguard Worker                       DataType::Type type,
306*795d594fSAndroid Build Coastguard Worker                       Address field_addr,
307*795d594fSAndroid Build Coastguard Worker                       Register base,
308*795d594fSAndroid Build Coastguard Worker                       bool is_volatile,
309*795d594fSAndroid Build Coastguard Worker                       bool value_can_be_null,
310*795d594fSAndroid Build Coastguard Worker                       WriteBarrierKind write_barrier_kind);
311*795d594fSAndroid Build Coastguard Worker 
312*795d594fSAndroid Build Coastguard Worker  private:
313*795d594fSAndroid Build Coastguard Worker   // Generate code for the given suspend check. If not null, `successor`
314*795d594fSAndroid Build Coastguard Worker   // is the block to branch to if the suspend check is not needed, and after
315*795d594fSAndroid Build Coastguard Worker   // the suspend call.
316*795d594fSAndroid Build Coastguard Worker   void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor);
317*795d594fSAndroid Build Coastguard Worker   void GenerateClassInitializationCheck(SlowPathCode* slow_path, Register class_reg);
318*795d594fSAndroid Build Coastguard Worker   void GenerateBitstringTypeCheckCompare(HTypeCheckInstruction* check, Register temp);
319*795d594fSAndroid Build Coastguard Worker   void HandleBitwiseOperation(HBinaryOperation* instruction);
320*795d594fSAndroid Build Coastguard Worker   void GenerateDivRemIntegral(HBinaryOperation* instruction);
321*795d594fSAndroid Build Coastguard Worker   void DivRemOneOrMinusOne(HBinaryOperation* instruction);
322*795d594fSAndroid Build Coastguard Worker   void DivByPowerOfTwo(HDiv* instruction);
323*795d594fSAndroid Build Coastguard Worker   void RemByPowerOfTwo(HRem* instruction);
324*795d594fSAndroid Build Coastguard Worker   void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
325*795d594fSAndroid Build Coastguard Worker   void GenerateRemFP(HRem* rem);
326*795d594fSAndroid Build Coastguard Worker   void HandleCondition(HCondition* condition);
327*795d594fSAndroid Build Coastguard Worker   void HandleShift(HBinaryOperation* instruction);
328*795d594fSAndroid Build Coastguard Worker   void GenerateShlLong(const Location& loc, Register shifter);
329*795d594fSAndroid Build Coastguard Worker   void GenerateShrLong(const Location& loc, Register shifter);
330*795d594fSAndroid Build Coastguard Worker   void GenerateUShrLong(const Location& loc, Register shifter);
331*795d594fSAndroid Build Coastguard Worker   void GenerateShlLong(const Location& loc, int shift);
332*795d594fSAndroid Build Coastguard Worker   void GenerateShrLong(const Location& loc, int shift);
333*795d594fSAndroid Build Coastguard Worker   void GenerateUShrLong(const Location& loc, int shift);
334*795d594fSAndroid Build Coastguard Worker   void GenerateMinMaxInt(LocationSummary* locations, bool is_min, DataType::Type type);
335*795d594fSAndroid Build Coastguard Worker   void GenerateMinMaxFP(LocationSummary* locations, bool is_min, DataType::Type type);
336*795d594fSAndroid Build Coastguard Worker   void GenerateMinMax(HBinaryOperation* minmax, bool is_min);
337*795d594fSAndroid Build Coastguard Worker 
338*795d594fSAndroid Build Coastguard Worker   void HandleFieldSet(HInstruction* instruction,
339*795d594fSAndroid Build Coastguard Worker                       const FieldInfo& field_info,
340*795d594fSAndroid Build Coastguard Worker                       bool value_can_be_null,
341*795d594fSAndroid Build Coastguard Worker                       WriteBarrierKind write_barrier_kind);
342*795d594fSAndroid Build Coastguard Worker   void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
343*795d594fSAndroid Build Coastguard Worker   void HandleRotate(HBinaryOperation* rotate);
344*795d594fSAndroid Build Coastguard Worker 
345*795d594fSAndroid Build Coastguard Worker   // Generate a heap reference load using one register `out`:
346*795d594fSAndroid Build Coastguard Worker   //
347*795d594fSAndroid Build Coastguard Worker   //   out <- *(out + offset)
348*795d594fSAndroid Build Coastguard Worker   //
349*795d594fSAndroid Build Coastguard Worker   // while honoring heap poisoning and/or read barriers (if any).
350*795d594fSAndroid Build Coastguard Worker   //
351*795d594fSAndroid Build Coastguard Worker   // Location `maybe_temp` is used when generating a read barrier and
352*795d594fSAndroid Build Coastguard Worker   // shall be a register in that case; it may be an invalid location
353*795d594fSAndroid Build Coastguard Worker   // otherwise.
354*795d594fSAndroid Build Coastguard Worker   void GenerateReferenceLoadOneRegister(HInstruction* instruction,
355*795d594fSAndroid Build Coastguard Worker                                         Location out,
356*795d594fSAndroid Build Coastguard Worker                                         uint32_t offset,
357*795d594fSAndroid Build Coastguard Worker                                         Location maybe_temp,
358*795d594fSAndroid Build Coastguard Worker                                         ReadBarrierOption read_barrier_option);
359*795d594fSAndroid Build Coastguard Worker   // Generate a heap reference load using two different registers
360*795d594fSAndroid Build Coastguard Worker   // `out` and `obj`:
361*795d594fSAndroid Build Coastguard Worker   //
362*795d594fSAndroid Build Coastguard Worker   //   out <- *(obj + offset)
363*795d594fSAndroid Build Coastguard Worker   //
364*795d594fSAndroid Build Coastguard Worker   // while honoring heap poisoning and/or read barriers (if any).
365*795d594fSAndroid Build Coastguard Worker   //
366*795d594fSAndroid Build Coastguard Worker   // Location `maybe_temp` is used when generating a Baker's (fast
367*795d594fSAndroid Build Coastguard Worker   // path) read barrier and shall be a register in that case; it may
368*795d594fSAndroid Build Coastguard Worker   // be an invalid location otherwise.
369*795d594fSAndroid Build Coastguard Worker   void GenerateReferenceLoadTwoRegisters(HInstruction* instruction,
370*795d594fSAndroid Build Coastguard Worker                                          Location out,
371*795d594fSAndroid Build Coastguard Worker                                          Location obj,
372*795d594fSAndroid Build Coastguard Worker                                          uint32_t offset,
373*795d594fSAndroid Build Coastguard Worker                                          ReadBarrierOption read_barrier_option);
374*795d594fSAndroid Build Coastguard Worker 
375*795d594fSAndroid Build Coastguard Worker   // Push value to FPU stack. `is_fp` specifies whether the value is floating point or not.
376*795d594fSAndroid Build Coastguard Worker   // `is_wide` specifies whether it is long/double or not.
377*795d594fSAndroid Build Coastguard Worker   void PushOntoFPStack(Location source, uint32_t temp_offset,
378*795d594fSAndroid Build Coastguard Worker                        uint32_t stack_adjustment, bool is_fp, bool is_wide);
379*795d594fSAndroid Build Coastguard Worker 
380*795d594fSAndroid Build Coastguard Worker   template<class LabelType>
381*795d594fSAndroid Build Coastguard Worker   void GenerateTestAndBranch(HInstruction* instruction,
382*795d594fSAndroid Build Coastguard Worker                              size_t condition_input_index,
383*795d594fSAndroid Build Coastguard Worker                              LabelType* true_target,
384*795d594fSAndroid Build Coastguard Worker                              LabelType* false_target);
385*795d594fSAndroid Build Coastguard Worker   template<class LabelType>
386*795d594fSAndroid Build Coastguard Worker   void GenerateCompareTestAndBranch(HCondition* condition,
387*795d594fSAndroid Build Coastguard Worker                                     LabelType* true_target,
388*795d594fSAndroid Build Coastguard Worker                                     LabelType* false_target);
389*795d594fSAndroid Build Coastguard Worker   template<class LabelType>
390*795d594fSAndroid Build Coastguard Worker   void GenerateFPJumps(HCondition* cond, LabelType* true_label, LabelType* false_label);
391*795d594fSAndroid Build Coastguard Worker   template<class LabelType>
392*795d594fSAndroid Build Coastguard Worker   void GenerateLongComparesAndJumps(HCondition* cond,
393*795d594fSAndroid Build Coastguard Worker                                     LabelType* true_label,
394*795d594fSAndroid Build Coastguard Worker                                     LabelType* false_label);
395*795d594fSAndroid Build Coastguard Worker 
396*795d594fSAndroid Build Coastguard Worker   void HandleGoto(HInstruction* got, HBasicBlock* successor);
397*795d594fSAndroid Build Coastguard Worker   void GenPackedSwitchWithCompares(Register value_reg,
398*795d594fSAndroid Build Coastguard Worker                                    int32_t lower_bound,
399*795d594fSAndroid Build Coastguard Worker                                    uint32_t num_entries,
400*795d594fSAndroid Build Coastguard Worker                                    HBasicBlock* switch_block,
401*795d594fSAndroid Build Coastguard Worker                                    HBasicBlock* default_block);
402*795d594fSAndroid Build Coastguard Worker 
403*795d594fSAndroid Build Coastguard Worker   void GenerateFPCompare(Location lhs, Location rhs, HInstruction* insn, bool is_double);
404*795d594fSAndroid Build Coastguard Worker   bool CpuHasAvxFeatureFlag();
405*795d594fSAndroid Build Coastguard Worker   bool CpuHasAvx2FeatureFlag();
406*795d594fSAndroid Build Coastguard Worker 
407*795d594fSAndroid Build Coastguard Worker   void GenerateMethodEntryExitHook(HInstruction* instruction);
408*795d594fSAndroid Build Coastguard Worker 
409*795d594fSAndroid Build Coastguard Worker   X86Assembler* const assembler_;
410*795d594fSAndroid Build Coastguard Worker   CodeGeneratorX86* const codegen_;
411*795d594fSAndroid Build Coastguard Worker 
412*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86);
413*795d594fSAndroid Build Coastguard Worker };
414*795d594fSAndroid Build Coastguard Worker 
415*795d594fSAndroid Build Coastguard Worker class JumpTableRIPFixup;
416*795d594fSAndroid Build Coastguard Worker 
417*795d594fSAndroid Build Coastguard Worker class CodeGeneratorX86 : public CodeGenerator {
418*795d594fSAndroid Build Coastguard Worker  public:
419*795d594fSAndroid Build Coastguard Worker   CodeGeneratorX86(HGraph* graph,
420*795d594fSAndroid Build Coastguard Worker                    const CompilerOptions& compiler_options,
421*795d594fSAndroid Build Coastguard Worker                    OptimizingCompilerStats* stats = nullptr);
~CodeGeneratorX86()422*795d594fSAndroid Build Coastguard Worker   virtual ~CodeGeneratorX86() {}
423*795d594fSAndroid Build Coastguard Worker 
424*795d594fSAndroid Build Coastguard Worker   void GenerateFrameEntry() override;
425*795d594fSAndroid Build Coastguard Worker   void GenerateFrameExit() override;
426*795d594fSAndroid Build Coastguard Worker   void Bind(HBasicBlock* block) override;
427*795d594fSAndroid Build Coastguard Worker   void MoveConstant(Location destination, int32_t value) override;
428*795d594fSAndroid Build Coastguard Worker   void MoveLocation(Location dst, Location src, DataType::Type dst_type) override;
429*795d594fSAndroid Build Coastguard Worker   void AddLocationAsTemp(Location location, LocationSummary* locations) override;
430*795d594fSAndroid Build Coastguard Worker 
431*795d594fSAndroid Build Coastguard Worker   size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) override;
432*795d594fSAndroid Build Coastguard Worker   size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) override;
433*795d594fSAndroid Build Coastguard Worker   size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) override;
434*795d594fSAndroid Build Coastguard Worker   size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) override;
435*795d594fSAndroid Build Coastguard Worker 
436*795d594fSAndroid Build Coastguard Worker   // Generate code to invoke a runtime entry point.
437*795d594fSAndroid Build Coastguard Worker   void InvokeRuntime(QuickEntrypointEnum entrypoint,
438*795d594fSAndroid Build Coastguard Worker                      HInstruction* instruction,
439*795d594fSAndroid Build Coastguard Worker                      uint32_t dex_pc,
440*795d594fSAndroid Build Coastguard Worker                      SlowPathCode* slow_path = nullptr) override;
441*795d594fSAndroid Build Coastguard Worker 
442*795d594fSAndroid Build Coastguard Worker   // Generate code to invoke a runtime entry point, but do not record
443*795d594fSAndroid Build Coastguard Worker   // PC-related information in a stack map.
444*795d594fSAndroid Build Coastguard Worker   void InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_offset,
445*795d594fSAndroid Build Coastguard Worker                                            HInstruction* instruction,
446*795d594fSAndroid Build Coastguard Worker                                            SlowPathCode* slow_path);
447*795d594fSAndroid Build Coastguard Worker 
448*795d594fSAndroid Build Coastguard Worker   void GenerateInvokeRuntime(int32_t entry_point_offset);
449*795d594fSAndroid Build Coastguard Worker 
GetWordSize()450*795d594fSAndroid Build Coastguard Worker   size_t GetWordSize() const override {
451*795d594fSAndroid Build Coastguard Worker     return kX86WordSize;
452*795d594fSAndroid Build Coastguard Worker   }
453*795d594fSAndroid Build Coastguard Worker 
GetSlowPathFPWidth()454*795d594fSAndroid Build Coastguard Worker   size_t GetSlowPathFPWidth() const override {
455*795d594fSAndroid Build Coastguard Worker     return GetGraph()->HasSIMD()
456*795d594fSAndroid Build Coastguard Worker         ? GetSIMDRegisterWidth()
457*795d594fSAndroid Build Coastguard Worker         : 2 * kX86WordSize;  //  8 bytes == 2 words for each spill
458*795d594fSAndroid Build Coastguard Worker   }
459*795d594fSAndroid Build Coastguard Worker 
GetCalleePreservedFPWidth()460*795d594fSAndroid Build Coastguard Worker   size_t GetCalleePreservedFPWidth() const override {
461*795d594fSAndroid Build Coastguard Worker     return 2 * kX86WordSize;
462*795d594fSAndroid Build Coastguard Worker   }
463*795d594fSAndroid Build Coastguard Worker 
GetSIMDRegisterWidth()464*795d594fSAndroid Build Coastguard Worker   size_t GetSIMDRegisterWidth() const override {
465*795d594fSAndroid Build Coastguard Worker     return 4 * kX86WordSize;
466*795d594fSAndroid Build Coastguard Worker   }
467*795d594fSAndroid Build Coastguard Worker 
GetLocationBuilder()468*795d594fSAndroid Build Coastguard Worker   HGraphVisitor* GetLocationBuilder() override {
469*795d594fSAndroid Build Coastguard Worker     return &location_builder_;
470*795d594fSAndroid Build Coastguard Worker   }
471*795d594fSAndroid Build Coastguard Worker 
GetInstructionVisitor()472*795d594fSAndroid Build Coastguard Worker   HGraphVisitor* GetInstructionVisitor() override {
473*795d594fSAndroid Build Coastguard Worker     return &instruction_visitor_;
474*795d594fSAndroid Build Coastguard Worker   }
475*795d594fSAndroid Build Coastguard Worker 
GetAssembler()476*795d594fSAndroid Build Coastguard Worker   X86Assembler* GetAssembler() override {
477*795d594fSAndroid Build Coastguard Worker     return &assembler_;
478*795d594fSAndroid Build Coastguard Worker   }
479*795d594fSAndroid Build Coastguard Worker 
GetAssembler()480*795d594fSAndroid Build Coastguard Worker   const X86Assembler& GetAssembler() const override {
481*795d594fSAndroid Build Coastguard Worker     return assembler_;
482*795d594fSAndroid Build Coastguard Worker   }
483*795d594fSAndroid Build Coastguard Worker 
GetAddressOf(HBasicBlock * block)484*795d594fSAndroid Build Coastguard Worker   uintptr_t GetAddressOf(HBasicBlock* block) override {
485*795d594fSAndroid Build Coastguard Worker     return GetLabelOf(block)->Position();
486*795d594fSAndroid Build Coastguard Worker   }
487*795d594fSAndroid Build Coastguard Worker 
488*795d594fSAndroid Build Coastguard Worker   void SetupBlockedRegisters() const override;
489*795d594fSAndroid Build Coastguard Worker 
490*795d594fSAndroid Build Coastguard Worker   void DumpCoreRegister(std::ostream& stream, int reg) const override;
491*795d594fSAndroid Build Coastguard Worker   void DumpFloatingPointRegister(std::ostream& stream, int reg) const override;
492*795d594fSAndroid Build Coastguard Worker 
GetMoveResolver()493*795d594fSAndroid Build Coastguard Worker   ParallelMoveResolverX86* GetMoveResolver() override {
494*795d594fSAndroid Build Coastguard Worker     return &move_resolver_;
495*795d594fSAndroid Build Coastguard Worker   }
496*795d594fSAndroid Build Coastguard Worker 
GetInstructionSet()497*795d594fSAndroid Build Coastguard Worker   InstructionSet GetInstructionSet() const override {
498*795d594fSAndroid Build Coastguard Worker     return InstructionSet::kX86;
499*795d594fSAndroid Build Coastguard Worker   }
500*795d594fSAndroid Build Coastguard Worker 
501*795d594fSAndroid Build Coastguard Worker   const X86InstructionSetFeatures& GetInstructionSetFeatures() const;
502*795d594fSAndroid Build Coastguard Worker 
503*795d594fSAndroid Build Coastguard Worker   // Helper method to move a 32bits value between two locations.
504*795d594fSAndroid Build Coastguard Worker   void Move32(Location destination, Location source);
505*795d594fSAndroid Build Coastguard Worker   // Helper method to move a 64bits value between two locations.
506*795d594fSAndroid Build Coastguard Worker   void Move64(Location destination, Location source);
507*795d594fSAndroid Build Coastguard Worker   // Helper method to load a value from an address to a register.
508*795d594fSAndroid Build Coastguard Worker   void LoadFromMemoryNoBarrier(DataType::Type dst_type,
509*795d594fSAndroid Build Coastguard Worker                                Location dst,
510*795d594fSAndroid Build Coastguard Worker                                Address src,
511*795d594fSAndroid Build Coastguard Worker                                HInstruction* instr = nullptr,
512*795d594fSAndroid Build Coastguard Worker                                XmmRegister temp = kNoXmmRegister,
513*795d594fSAndroid Build Coastguard Worker                                bool is_atomic_load = false);
514*795d594fSAndroid Build Coastguard Worker   // Helper method to move a primitive value from a location to an address.
515*795d594fSAndroid Build Coastguard Worker   void MoveToMemory(DataType::Type src_type,
516*795d594fSAndroid Build Coastguard Worker                     Location src,
517*795d594fSAndroid Build Coastguard Worker                     Register dst_base,
518*795d594fSAndroid Build Coastguard Worker                     Register dst_index = Register::kNoRegister,
519*795d594fSAndroid Build Coastguard Worker                     ScaleFactor dst_scale = TIMES_1,
520*795d594fSAndroid Build Coastguard Worker                     int32_t dst_disp = 0);
521*795d594fSAndroid Build Coastguard Worker 
522*795d594fSAndroid Build Coastguard Worker   // Check if the desired_string_load_kind is supported. If it is, return it,
523*795d594fSAndroid Build Coastguard Worker   // otherwise return a fall-back kind that should be used instead.
524*795d594fSAndroid Build Coastguard Worker   HLoadString::LoadKind GetSupportedLoadStringKind(
525*795d594fSAndroid Build Coastguard Worker       HLoadString::LoadKind desired_string_load_kind) override;
526*795d594fSAndroid Build Coastguard Worker 
527*795d594fSAndroid Build Coastguard Worker   // Check if the desired_class_load_kind is supported. If it is, return it,
528*795d594fSAndroid Build Coastguard Worker   // otherwise return a fall-back kind that should be used instead.
529*795d594fSAndroid Build Coastguard Worker   HLoadClass::LoadKind GetSupportedLoadClassKind(
530*795d594fSAndroid Build Coastguard Worker       HLoadClass::LoadKind desired_class_load_kind) override;
531*795d594fSAndroid Build Coastguard Worker 
532*795d594fSAndroid Build Coastguard Worker   // Check if the desired_dispatch_info is supported. If it is, return it,
533*795d594fSAndroid Build Coastguard Worker   // otherwise return a fall-back info that should be used instead.
534*795d594fSAndroid Build Coastguard Worker   HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
535*795d594fSAndroid Build Coastguard Worker       const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
536*795d594fSAndroid Build Coastguard Worker       ArtMethod* method) override;
537*795d594fSAndroid Build Coastguard Worker 
538*795d594fSAndroid Build Coastguard Worker   void LoadMethod(MethodLoadKind load_kind, Location temp, HInvoke* invoke);
539*795d594fSAndroid Build Coastguard Worker   // Generate a call to a static or direct method.
540*795d594fSAndroid Build Coastguard Worker   void GenerateStaticOrDirectCall(
541*795d594fSAndroid Build Coastguard Worker       HInvokeStaticOrDirect* invoke, Location temp, SlowPathCode* slow_path = nullptr) override;
542*795d594fSAndroid Build Coastguard Worker   // Generate a call to a virtual method.
543*795d594fSAndroid Build Coastguard Worker   void GenerateVirtualCall(
544*795d594fSAndroid Build Coastguard Worker       HInvokeVirtual* invoke, Location temp, SlowPathCode* slow_path = nullptr) override;
545*795d594fSAndroid Build Coastguard Worker 
546*795d594fSAndroid Build Coastguard Worker   void RecordBootImageIntrinsicPatch(HX86ComputeBaseMethodAddress* method_address,
547*795d594fSAndroid Build Coastguard Worker                                      uint32_t intrinsic_data);
548*795d594fSAndroid Build Coastguard Worker   void RecordBootImageRelRoPatch(HX86ComputeBaseMethodAddress* method_address,
549*795d594fSAndroid Build Coastguard Worker                                  uint32_t boot_image_offset);
550*795d594fSAndroid Build Coastguard Worker   void RecordBootImageMethodPatch(HInvoke* invoke);
551*795d594fSAndroid Build Coastguard Worker   void RecordAppImageMethodPatch(HInvoke* invoke);
552*795d594fSAndroid Build Coastguard Worker   void RecordMethodBssEntryPatch(HInvoke* invoke);
553*795d594fSAndroid Build Coastguard Worker   void RecordBootImageTypePatch(HLoadClass* load_class);
554*795d594fSAndroid Build Coastguard Worker   void RecordAppImageTypePatch(HLoadClass* load_class);
555*795d594fSAndroid Build Coastguard Worker   Label* NewTypeBssEntryPatch(HLoadClass* load_class);
556*795d594fSAndroid Build Coastguard Worker   void RecordBootImageStringPatch(HLoadString* load_string);
557*795d594fSAndroid Build Coastguard Worker   Label* NewStringBssEntryPatch(HLoadString* load_string);
558*795d594fSAndroid Build Coastguard Worker   void RecordBootImageJniEntrypointPatch(HInvokeStaticOrDirect* invoke);
559*795d594fSAndroid Build Coastguard Worker 
560*795d594fSAndroid Build Coastguard Worker   void LoadBootImageAddress(Register reg,
561*795d594fSAndroid Build Coastguard Worker                             uint32_t boot_image_reference,
562*795d594fSAndroid Build Coastguard Worker                             HInvokeStaticOrDirect* invoke);
563*795d594fSAndroid Build Coastguard Worker   void LoadIntrinsicDeclaringClass(Register reg, HInvokeStaticOrDirect* invoke);
564*795d594fSAndroid Build Coastguard Worker 
565*795d594fSAndroid Build Coastguard Worker   Label* NewJitRootStringPatch(const DexFile& dex_file,
566*795d594fSAndroid Build Coastguard Worker                                dex::StringIndex string_index,
567*795d594fSAndroid Build Coastguard Worker                                Handle<mirror::String> handle);
568*795d594fSAndroid Build Coastguard Worker   Label* NewJitRootClassPatch(const DexFile& dex_file,
569*795d594fSAndroid Build Coastguard Worker                               dex::TypeIndex type_index,
570*795d594fSAndroid Build Coastguard Worker                               Handle<mirror::Class> handle);
571*795d594fSAndroid Build Coastguard Worker 
572*795d594fSAndroid Build Coastguard Worker   void MoveFromReturnRegister(Location trg, DataType::Type type) override;
573*795d594fSAndroid Build Coastguard Worker 
574*795d594fSAndroid Build Coastguard Worker   // Emit linker patches.
575*795d594fSAndroid Build Coastguard Worker   void EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* linker_patches) override;
576*795d594fSAndroid Build Coastguard Worker 
577*795d594fSAndroid Build Coastguard Worker   void PatchJitRootUse(uint8_t* code,
578*795d594fSAndroid Build Coastguard Worker                        const uint8_t* roots_data,
579*795d594fSAndroid Build Coastguard Worker                        const PatchInfo<Label>& info,
580*795d594fSAndroid Build Coastguard Worker                        uint64_t index_in_table) const;
581*795d594fSAndroid Build Coastguard Worker   void EmitJitRootPatches(uint8_t* code, const uint8_t* roots_data) override;
582*795d594fSAndroid Build Coastguard Worker 
583*795d594fSAndroid Build Coastguard Worker   // Emit a write barrier if:
584*795d594fSAndroid Build Coastguard Worker   // A) emit_null_check is false
585*795d594fSAndroid Build Coastguard Worker   // B) emit_null_check is true, and value is not null.
586*795d594fSAndroid Build Coastguard Worker   void MaybeMarkGCCard(
587*795d594fSAndroid Build Coastguard Worker       Register temp, Register card, Register object, Register value, bool emit_null_check);
588*795d594fSAndroid Build Coastguard Worker 
589*795d594fSAndroid Build Coastguard Worker   // Emit a write barrier unconditionally.
590*795d594fSAndroid Build Coastguard Worker   void MarkGCCard(Register temp, Register card, Register object);
591*795d594fSAndroid Build Coastguard Worker 
592*795d594fSAndroid Build Coastguard Worker   // Crash if the card table is not valid. This check is only emitted for the CC GC. We assert
593*795d594fSAndroid Build Coastguard Worker   // `(!clean || !self->is_gc_marking)`, since the card table should not be set to clean when the CC
594*795d594fSAndroid Build Coastguard Worker   // GC is marking for eliminated write barriers.
595*795d594fSAndroid Build Coastguard Worker   void CheckGCCardIsValid(Register temp, Register card, Register object);
596*795d594fSAndroid Build Coastguard Worker 
597*795d594fSAndroid Build Coastguard Worker   void GenerateMemoryBarrier(MemBarrierKind kind);
598*795d594fSAndroid Build Coastguard Worker 
GetLabelOf(HBasicBlock * block)599*795d594fSAndroid Build Coastguard Worker   Label* GetLabelOf(HBasicBlock* block) const {
600*795d594fSAndroid Build Coastguard Worker     return CommonGetLabelOf<Label>(block_labels_, block);
601*795d594fSAndroid Build Coastguard Worker   }
602*795d594fSAndroid Build Coastguard Worker 
Initialize()603*795d594fSAndroid Build Coastguard Worker   void Initialize() override {
604*795d594fSAndroid Build Coastguard Worker     block_labels_ = CommonInitializeLabels<Label>();
605*795d594fSAndroid Build Coastguard Worker   }
606*795d594fSAndroid Build Coastguard Worker 
NeedsTwoRegisters(DataType::Type type)607*795d594fSAndroid Build Coastguard Worker   bool NeedsTwoRegisters(DataType::Type type) const override {
608*795d594fSAndroid Build Coastguard Worker     return type == DataType::Type::kInt64;
609*795d594fSAndroid Build Coastguard Worker   }
610*795d594fSAndroid Build Coastguard Worker 
ShouldSplitLongMoves()611*795d594fSAndroid Build Coastguard Worker   bool ShouldSplitLongMoves() const override { return true; }
612*795d594fSAndroid Build Coastguard Worker 
GetFrameEntryLabel()613*795d594fSAndroid Build Coastguard Worker   Label* GetFrameEntryLabel() { return &frame_entry_label_; }
614*795d594fSAndroid Build Coastguard Worker 
AddMethodAddressOffset(HX86ComputeBaseMethodAddress * method_base,int32_t offset)615*795d594fSAndroid Build Coastguard Worker   void AddMethodAddressOffset(HX86ComputeBaseMethodAddress* method_base, int32_t offset) {
616*795d594fSAndroid Build Coastguard Worker     method_address_offset_.Put(method_base->GetId(), offset);
617*795d594fSAndroid Build Coastguard Worker   }
618*795d594fSAndroid Build Coastguard Worker 
GetMethodAddressOffset(HX86ComputeBaseMethodAddress * method_base)619*795d594fSAndroid Build Coastguard Worker   int32_t GetMethodAddressOffset(HX86ComputeBaseMethodAddress* method_base) const {
620*795d594fSAndroid Build Coastguard Worker     return method_address_offset_.Get(method_base->GetId());
621*795d594fSAndroid Build Coastguard Worker   }
622*795d594fSAndroid Build Coastguard Worker 
ConstantAreaStart()623*795d594fSAndroid Build Coastguard Worker   int32_t ConstantAreaStart() const {
624*795d594fSAndroid Build Coastguard Worker     return constant_area_start_;
625*795d594fSAndroid Build Coastguard Worker   }
626*795d594fSAndroid Build Coastguard Worker 
627*795d594fSAndroid Build Coastguard Worker   Address LiteralDoubleAddress(double v, HX86ComputeBaseMethodAddress* method_base, Register reg);
628*795d594fSAndroid Build Coastguard Worker   Address LiteralFloatAddress(float v, HX86ComputeBaseMethodAddress* method_base, Register reg);
629*795d594fSAndroid Build Coastguard Worker   Address LiteralInt32Address(int32_t v, HX86ComputeBaseMethodAddress* method_base, Register reg);
630*795d594fSAndroid Build Coastguard Worker   Address LiteralInt64Address(int64_t v, HX86ComputeBaseMethodAddress* method_base, Register reg);
631*795d594fSAndroid Build Coastguard Worker 
632*795d594fSAndroid Build Coastguard Worker   // Load a 32-bit value into a register in the most efficient manner.
633*795d594fSAndroid Build Coastguard Worker   void Load32BitValue(Register dest, int32_t value);
634*795d594fSAndroid Build Coastguard Worker 
635*795d594fSAndroid Build Coastguard Worker   // Compare a register with a 32-bit value in the most efficient manner.
636*795d594fSAndroid Build Coastguard Worker   void Compare32BitValue(Register dest, int32_t value);
637*795d594fSAndroid Build Coastguard Worker 
638*795d594fSAndroid Build Coastguard Worker   // Compare int values. Supports only register locations for `lhs`.
639*795d594fSAndroid Build Coastguard Worker   void GenerateIntCompare(Location lhs, Location rhs);
640*795d594fSAndroid Build Coastguard Worker   void GenerateIntCompare(Register lhs, Location rhs);
641*795d594fSAndroid Build Coastguard Worker 
642*795d594fSAndroid Build Coastguard Worker   // Construct address for array access.
643*795d594fSAndroid Build Coastguard Worker   static Address ArrayAddress(Register obj,
644*795d594fSAndroid Build Coastguard Worker                               Location index,
645*795d594fSAndroid Build Coastguard Worker                               ScaleFactor scale,
646*795d594fSAndroid Build Coastguard Worker                               uint32_t data_offset);
647*795d594fSAndroid Build Coastguard Worker 
648*795d594fSAndroid Build Coastguard Worker   Address LiteralCaseTable(HX86PackedSwitch* switch_instr, Register reg, Register value);
649*795d594fSAndroid Build Coastguard Worker 
650*795d594fSAndroid Build Coastguard Worker   void Finalize() override;
651*795d594fSAndroid Build Coastguard Worker 
652*795d594fSAndroid Build Coastguard Worker   // Fast path implementation of ReadBarrier::Barrier for a heap
653*795d594fSAndroid Build Coastguard Worker   // reference field load when Baker's read barriers are used.
654*795d594fSAndroid Build Coastguard Worker   void GenerateFieldLoadWithBakerReadBarrier(HInstruction* instruction,
655*795d594fSAndroid Build Coastguard Worker                                              Location ref,
656*795d594fSAndroid Build Coastguard Worker                                              Register obj,
657*795d594fSAndroid Build Coastguard Worker                                              uint32_t offset,
658*795d594fSAndroid Build Coastguard Worker                                              bool needs_null_check);
659*795d594fSAndroid Build Coastguard Worker   // Fast path implementation of ReadBarrier::Barrier for a heap
660*795d594fSAndroid Build Coastguard Worker   // reference array load when Baker's read barriers are used.
661*795d594fSAndroid Build Coastguard Worker   void GenerateArrayLoadWithBakerReadBarrier(HInstruction* instruction,
662*795d594fSAndroid Build Coastguard Worker                                              Location ref,
663*795d594fSAndroid Build Coastguard Worker                                              Register obj,
664*795d594fSAndroid Build Coastguard Worker                                              uint32_t data_offset,
665*795d594fSAndroid Build Coastguard Worker                                              Location index,
666*795d594fSAndroid Build Coastguard Worker                                              bool needs_null_check);
667*795d594fSAndroid Build Coastguard Worker   // Factored implementation, used by GenerateFieldLoadWithBakerReadBarrier,
668*795d594fSAndroid Build Coastguard Worker   // GenerateArrayLoadWithBakerReadBarrier and some intrinsics.
669*795d594fSAndroid Build Coastguard Worker   //
670*795d594fSAndroid Build Coastguard Worker   // Load the object reference located at address `src`, held by
671*795d594fSAndroid Build Coastguard Worker   // object `obj`, into `ref`, and mark it if needed.  The base of
672*795d594fSAndroid Build Coastguard Worker   // address `src` must be `obj`.
673*795d594fSAndroid Build Coastguard Worker   //
674*795d594fSAndroid Build Coastguard Worker   // If `always_update_field` is true, the value of the reference is
675*795d594fSAndroid Build Coastguard Worker   // atomically updated in the holder (`obj`).  This operation
676*795d594fSAndroid Build Coastguard Worker   // requires a temporary register, which must be provided as a
677*795d594fSAndroid Build Coastguard Worker   // non-null pointer (`temp`).
678*795d594fSAndroid Build Coastguard Worker   void GenerateReferenceLoadWithBakerReadBarrier(HInstruction* instruction,
679*795d594fSAndroid Build Coastguard Worker                                                  Location ref,
680*795d594fSAndroid Build Coastguard Worker                                                  Register obj,
681*795d594fSAndroid Build Coastguard Worker                                                  const Address& src,
682*795d594fSAndroid Build Coastguard Worker                                                  bool needs_null_check,
683*795d594fSAndroid Build Coastguard Worker                                                  bool always_update_field = false,
684*795d594fSAndroid Build Coastguard Worker                                                  Register* temp = nullptr);
685*795d594fSAndroid Build Coastguard Worker 
686*795d594fSAndroid Build Coastguard Worker   // Generate a read barrier for a heap reference within `instruction`
687*795d594fSAndroid Build Coastguard Worker   // using a slow path.
688*795d594fSAndroid Build Coastguard Worker   //
689*795d594fSAndroid Build Coastguard Worker   // A read barrier for an object reference read from the heap is
690*795d594fSAndroid Build Coastguard Worker   // implemented as a call to the artReadBarrierSlow runtime entry
691*795d594fSAndroid Build Coastguard Worker   // point, which is passed the values in locations `ref`, `obj`, and
692*795d594fSAndroid Build Coastguard Worker   // `offset`:
693*795d594fSAndroid Build Coastguard Worker   //
694*795d594fSAndroid Build Coastguard Worker   //   mirror::Object* artReadBarrierSlow(mirror::Object* ref,
695*795d594fSAndroid Build Coastguard Worker   //                                      mirror::Object* obj,
696*795d594fSAndroid Build Coastguard Worker   //                                      uint32_t offset);
697*795d594fSAndroid Build Coastguard Worker   //
698*795d594fSAndroid Build Coastguard Worker   // The `out` location contains the value returned by
699*795d594fSAndroid Build Coastguard Worker   // artReadBarrierSlow.
700*795d594fSAndroid Build Coastguard Worker   //
701*795d594fSAndroid Build Coastguard Worker   // When `index` is provided (i.e. for array accesses), the offset
702*795d594fSAndroid Build Coastguard Worker   // value passed to artReadBarrierSlow is adjusted to take `index`
703*795d594fSAndroid Build Coastguard Worker   // into account.
704*795d594fSAndroid Build Coastguard Worker   void GenerateReadBarrierSlow(HInstruction* instruction,
705*795d594fSAndroid Build Coastguard Worker                                Location out,
706*795d594fSAndroid Build Coastguard Worker                                Location ref,
707*795d594fSAndroid Build Coastguard Worker                                Location obj,
708*795d594fSAndroid Build Coastguard Worker                                uint32_t offset,
709*795d594fSAndroid Build Coastguard Worker                                Location index = Location::NoLocation());
710*795d594fSAndroid Build Coastguard Worker 
711*795d594fSAndroid Build Coastguard Worker   // If read barriers are enabled, generate a read barrier for a heap
712*795d594fSAndroid Build Coastguard Worker   // reference using a slow path. If heap poisoning is enabled, also
713*795d594fSAndroid Build Coastguard Worker   // unpoison the reference in `out`.
714*795d594fSAndroid Build Coastguard Worker   void MaybeGenerateReadBarrierSlow(HInstruction* instruction,
715*795d594fSAndroid Build Coastguard Worker                                     Location out,
716*795d594fSAndroid Build Coastguard Worker                                     Location ref,
717*795d594fSAndroid Build Coastguard Worker                                     Location obj,
718*795d594fSAndroid Build Coastguard Worker                                     uint32_t offset,
719*795d594fSAndroid Build Coastguard Worker                                     Location index = Location::NoLocation());
720*795d594fSAndroid Build Coastguard Worker 
721*795d594fSAndroid Build Coastguard Worker   // Generate a read barrier for a GC root within `instruction` using
722*795d594fSAndroid Build Coastguard Worker   // a slow path.
723*795d594fSAndroid Build Coastguard Worker   //
724*795d594fSAndroid Build Coastguard Worker   // A read barrier for an object reference GC root is implemented as
725*795d594fSAndroid Build Coastguard Worker   // a call to the artReadBarrierForRootSlow runtime entry point,
726*795d594fSAndroid Build Coastguard Worker   // which is passed the value in location `root`:
727*795d594fSAndroid Build Coastguard Worker   //
728*795d594fSAndroid Build Coastguard Worker   //   mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root);
729*795d594fSAndroid Build Coastguard Worker   //
730*795d594fSAndroid Build Coastguard Worker   // The `out` location contains the value returned by
731*795d594fSAndroid Build Coastguard Worker   // artReadBarrierForRootSlow.
732*795d594fSAndroid Build Coastguard Worker   void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root);
733*795d594fSAndroid Build Coastguard Worker 
734*795d594fSAndroid Build Coastguard Worker   // Ensure that prior stores complete to memory before subsequent loads.
735*795d594fSAndroid Build Coastguard Worker   // The locked add implementation will avoid serializing device memory, but will
736*795d594fSAndroid Build Coastguard Worker   // touch (but not change) the top of the stack.
737*795d594fSAndroid Build Coastguard Worker   // The 'non_temporal' parameter should be used to ensure ordering of non-temporal stores.
738*795d594fSAndroid Build Coastguard Worker   void MemoryFence(bool non_temporal = false) {
739*795d594fSAndroid Build Coastguard Worker     if (!non_temporal) {
740*795d594fSAndroid Build Coastguard Worker       assembler_.lock()->addl(Address(ESP, 0), Immediate(0));
741*795d594fSAndroid Build Coastguard Worker     } else {
742*795d594fSAndroid Build Coastguard Worker       assembler_.mfence();
743*795d594fSAndroid Build Coastguard Worker     }
744*795d594fSAndroid Build Coastguard Worker   }
745*795d594fSAndroid Build Coastguard Worker 
746*795d594fSAndroid Build Coastguard Worker   void IncreaseFrame(size_t adjustment) override;
747*795d594fSAndroid Build Coastguard Worker   void DecreaseFrame(size_t adjustment) override;
748*795d594fSAndroid Build Coastguard Worker 
749*795d594fSAndroid Build Coastguard Worker   void GenerateNop() override;
750*795d594fSAndroid Build Coastguard Worker   void GenerateImplicitNullCheck(HNullCheck* instruction) override;
751*795d594fSAndroid Build Coastguard Worker   void GenerateExplicitNullCheck(HNullCheck* instruction) override;
752*795d594fSAndroid Build Coastguard Worker 
753*795d594fSAndroid Build Coastguard Worker   void MaybeGenerateInlineCacheCheck(HInstruction* instruction, Register klass);
754*795d594fSAndroid Build Coastguard Worker   void MaybeIncrementHotness(HSuspendCheck* suspend_check, bool is_frame_entry);
755*795d594fSAndroid Build Coastguard Worker 
756*795d594fSAndroid Build Coastguard Worker   // When we don't know the proper offset for the value, we use kPlaceholder32BitOffset.
757*795d594fSAndroid Build Coastguard Worker   // The correct value will be inserted when processing Assembler fixups.
758*795d594fSAndroid Build Coastguard Worker   static constexpr int32_t kPlaceholder32BitOffset = 256;
759*795d594fSAndroid Build Coastguard Worker 
760*795d594fSAndroid Build Coastguard Worker  private:
761*795d594fSAndroid Build Coastguard Worker   struct X86PcRelativePatchInfo : PatchInfo<Label> {
X86PcRelativePatchInfoX86PcRelativePatchInfo762*795d594fSAndroid Build Coastguard Worker     X86PcRelativePatchInfo(HX86ComputeBaseMethodAddress* address,
763*795d594fSAndroid Build Coastguard Worker                            const DexFile* target_dex_file,
764*795d594fSAndroid Build Coastguard Worker                            uint32_t target_index)
765*795d594fSAndroid Build Coastguard Worker         : PatchInfo(target_dex_file, target_index),
766*795d594fSAndroid Build Coastguard Worker           method_address(address) {}
767*795d594fSAndroid Build Coastguard Worker     HX86ComputeBaseMethodAddress* method_address;
768*795d594fSAndroid Build Coastguard Worker   };
769*795d594fSAndroid Build Coastguard Worker 
770*795d594fSAndroid Build Coastguard Worker   template <linker::LinkerPatch (*Factory)(size_t, const DexFile*, uint32_t, uint32_t)>
771*795d594fSAndroid Build Coastguard Worker   void EmitPcRelativeLinkerPatches(const ArenaDeque<X86PcRelativePatchInfo>& infos,
772*795d594fSAndroid Build Coastguard Worker                                    ArenaVector<linker::LinkerPatch>* linker_patches);
773*795d594fSAndroid Build Coastguard Worker 
774*795d594fSAndroid Build Coastguard Worker   Register GetInvokeExtraParameter(HInvoke* invoke, Register temp);
775*795d594fSAndroid Build Coastguard Worker   Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp);
776*795d594fSAndroid Build Coastguard Worker 
777*795d594fSAndroid Build Coastguard Worker   // Labels for each block that will be compiled.
778*795d594fSAndroid Build Coastguard Worker   Label* block_labels_;  // Indexed by block id.
779*795d594fSAndroid Build Coastguard Worker   Label frame_entry_label_;
780*795d594fSAndroid Build Coastguard Worker   LocationsBuilderX86 location_builder_;
781*795d594fSAndroid Build Coastguard Worker   InstructionCodeGeneratorX86 instruction_visitor_;
782*795d594fSAndroid Build Coastguard Worker   ParallelMoveResolverX86 move_resolver_;
783*795d594fSAndroid Build Coastguard Worker   X86Assembler assembler_;
784*795d594fSAndroid Build Coastguard Worker 
785*795d594fSAndroid Build Coastguard Worker   // PC-relative method patch info for kBootImageLinkTimePcRelative.
786*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> boot_image_method_patches_;
787*795d594fSAndroid Build Coastguard Worker   // PC-relative method patch info for kAppImageRelRo.
788*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> app_image_method_patches_;
789*795d594fSAndroid Build Coastguard Worker   // PC-relative method patch info for kBssEntry.
790*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> method_bss_entry_patches_;
791*795d594fSAndroid Build Coastguard Worker   // PC-relative type patch info for kBootImageLinkTimePcRelative.
792*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> boot_image_type_patches_;
793*795d594fSAndroid Build Coastguard Worker   // PC-relative type patch info for kAppImageRelRo.
794*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> app_image_type_patches_;
795*795d594fSAndroid Build Coastguard Worker   // PC-relative type patch info for kBssEntry.
796*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> type_bss_entry_patches_;
797*795d594fSAndroid Build Coastguard Worker   // PC-relative public type patch info for kBssEntryPublic.
798*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> public_type_bss_entry_patches_;
799*795d594fSAndroid Build Coastguard Worker   // PC-relative package type patch info for kBssEntryPackage.
800*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> package_type_bss_entry_patches_;
801*795d594fSAndroid Build Coastguard Worker   // PC-relative String patch info for kBootImageLinkTimePcRelative.
802*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> boot_image_string_patches_;
803*795d594fSAndroid Build Coastguard Worker   // PC-relative String patch info for kBssEntry.
804*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> string_bss_entry_patches_;
805*795d594fSAndroid Build Coastguard Worker   // PC-relative method patch info for kBootImageLinkTimePcRelative+kCallCriticalNative.
806*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> boot_image_jni_entrypoint_patches_;
807*795d594fSAndroid Build Coastguard Worker   // PC-relative patch info for IntrinsicObjects for the boot image,
808*795d594fSAndroid Build Coastguard Worker   // and for method/type/string patches for kBootImageRelRo otherwise.
809*795d594fSAndroid Build Coastguard Worker   ArenaDeque<X86PcRelativePatchInfo> boot_image_other_patches_;
810*795d594fSAndroid Build Coastguard Worker 
811*795d594fSAndroid Build Coastguard Worker   // Patches for string root accesses in JIT compiled code.
812*795d594fSAndroid Build Coastguard Worker   ArenaDeque<PatchInfo<Label>> jit_string_patches_;
813*795d594fSAndroid Build Coastguard Worker   // Patches for class root accesses in JIT compiled code.
814*795d594fSAndroid Build Coastguard Worker   ArenaDeque<PatchInfo<Label>> jit_class_patches_;
815*795d594fSAndroid Build Coastguard Worker 
816*795d594fSAndroid Build Coastguard Worker   // Offset to the start of the constant area in the assembled code.
817*795d594fSAndroid Build Coastguard Worker   // Used for fixups to the constant area.
818*795d594fSAndroid Build Coastguard Worker   int32_t constant_area_start_;
819*795d594fSAndroid Build Coastguard Worker 
820*795d594fSAndroid Build Coastguard Worker   // Fixups for jump tables that need to be patched after the constant table is generated.
821*795d594fSAndroid Build Coastguard Worker   ArenaVector<JumpTableRIPFixup*> fixups_to_jump_tables_;
822*795d594fSAndroid Build Coastguard Worker 
823*795d594fSAndroid Build Coastguard Worker   // Maps a HX86ComputeBaseMethodAddress instruction id, to its offset in the
824*795d594fSAndroid Build Coastguard Worker   // compiled code.
825*795d594fSAndroid Build Coastguard Worker   ArenaSafeMap<uint32_t, int32_t> method_address_offset_;
826*795d594fSAndroid Build Coastguard Worker 
827*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86);
828*795d594fSAndroid Build Coastguard Worker };
829*795d594fSAndroid Build Coastguard Worker 
830*795d594fSAndroid Build Coastguard Worker }  // namespace x86
831*795d594fSAndroid Build Coastguard Worker }  // namespace art
832*795d594fSAndroid Build Coastguard Worker 
833*795d594fSAndroid Build Coastguard Worker #endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
834