code_generator_x86.h revision 0debae7bc89eb05f7a2bf7dccd223318fad7c88d
1734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller/*
2734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Copyright (C) 2014 The Android Open Source Project
3734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
4734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Licensed under the Apache License, Version 2.0 (the "License");
5734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * you may not use this file except in compliance with the License.
6734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * You may obtain a copy of the License at
7734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
8734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *      http://www.apache.org/licenses/LICENSE-2.0
9734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
10734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Unless required by applicable law or agreed to in writing, software
11734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * distributed under the License is distributed on an "AS IS" BASIS,
12734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * See the License for the specific language governing permissions and
14734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * limitations under the License.
15734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller */
16734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
17734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
18734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
19734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
20734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "code_generator.h"
21734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "dex/compiler_enums.h"
22734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "driver/compiler_options.h"
23734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "nodes.h"
24734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "parallel_move_resolver.h"
25734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "utils/x86/assembler_x86.h"
26734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
27734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillernamespace art {
28734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillernamespace x86 {
29734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
30734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Use a local definition to prevent copying mistakes.
31734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kX86WordSize = kX86PointerSize;
32734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
33734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass CodeGeneratorX86;
34734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
35734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
36734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX };
37734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
38734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr XmmRegister kParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 };
39734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters);
40734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
41734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX, EBX };
42734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kRuntimeParameterCoreRegistersLength =
43734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    arraysize(kRuntimeParameterCoreRegisters);
44734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr XmmRegister kRuntimeParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 };
45734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kRuntimeParameterFpuRegistersLength =
46734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    arraysize(kRuntimeParameterFpuRegisters);
47734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
48734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass InvokeRuntimeCallingConvention : public CallingConvention<Register, XmmRegister> {
49734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public:
50734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  InvokeRuntimeCallingConvention()
51734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      : CallingConvention(kRuntimeParameterCoreRegisters,
52734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                          kRuntimeParameterCoreRegistersLength,
53734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                          kRuntimeParameterFpuRegisters,
54734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                          kRuntimeParameterFpuRegistersLength,
55734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                          kX86PointerSize) {}
56734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
57734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private:
58734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
59734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
60734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
61734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass InvokeDexCallingConvention : public CallingConvention<Register, XmmRegister> {
62734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public:
63734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  InvokeDexCallingConvention() : CallingConvention(
64734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      kParameterCoreRegisters,
65734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      kParameterCoreRegistersLength,
66734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      kParameterFpuRegisters,
67734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      kParameterFpuRegistersLength,
68734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      kX86PointerSize) {}
69734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
70734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  RegisterPair GetRegisterPairAt(size_t argument_index) {
71734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
72734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return kParameterCorePairRegisters[argument_index];
73734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
74734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
75734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private:
76734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
77734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
78734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
79734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass InvokeDexCallingConventionVisitorX86 : public InvokeDexCallingConventionVisitor {
80734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public:
81d1d16998adea189d5f24a774aa06e0e4e5f3e7ebAurimas Liutikas  InvokeDexCallingConventionVisitorX86() {}
82d1d16998adea189d5f24a774aa06e0e4e5f3e7ebAurimas Liutikas  virtual ~InvokeDexCallingConventionVisitorX86() {}
83734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
84734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetNextLocation(Primitive::Type type) OVERRIDE;
85734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
86734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetMethodLocation() const OVERRIDE;
87734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
88734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private:
89734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  InvokeDexCallingConvention calling_convention;
90734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
91734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorX86);
92734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
93734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
94734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass FieldAccessCallingConventionX86 : public FieldAccessCallingConvention {
95734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public:
96734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  FieldAccessCallingConventionX86() {}
97734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
98734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetObjectLocation() const OVERRIDE {
99734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return Location::RegisterLocation(ECX);
100734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
101734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetFieldIndexLocation() const OVERRIDE {
102734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return Location::RegisterLocation(EAX);
103734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
104734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetReturnLocation(Primitive::Type type) const OVERRIDE {
105734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return Primitive::Is64BitType(type)
106734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        ? Location::RegisterPairLocation(EAX, EDX)
107734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        : Location::RegisterLocation(EAX);
108734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
109734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE {
110734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return Primitive::Is64BitType(type)
111734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        ? Location::RegisterPairLocation(EDX, EBX)
112734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        : (is_instance
113734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            ? Location::RegisterLocation(EDX)
114622cfadc8f0d294f875151fe1d8985e0553795eaMathias Agopian            : Location::RegisterLocation(ECX));
115734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
116734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetFpuLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE {
117734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return Location::FpuRegisterLocation(XMM0);
118734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
119734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
120734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private:
121734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionX86);
122734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
123734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
124734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass ParallelMoveResolverX86 : public ParallelMoveResolverWithSwap {
125734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public:
126734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  ParallelMoveResolverX86(ArenaAllocator* allocator, CodeGeneratorX86* codegen)
127734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      : ParallelMoveResolverWithSwap(allocator), codegen_(codegen) {}
128734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
129734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void EmitMove(size_t index) OVERRIDE;
130734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void EmitSwap(size_t index) OVERRIDE;
131734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void SpillScratch(int reg) OVERRIDE;
132734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void RestoreScratch(int reg) OVERRIDE;
133734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
134734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  X86Assembler* GetAssembler() const;
135734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
136734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private:
137734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Exchange(Register reg, int mem);
138734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Exchange(int mem1, int mem2);
139734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Exchange32(XmmRegister reg, int mem);
140734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void MoveMemoryToMemory32(int dst, int src);
141734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void MoveMemoryToMemory64(int dst, int src);
142734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
143734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  CodeGeneratorX86* const codegen_;
144734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
145734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverX86);
146734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
147734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
148734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass LocationsBuilderX86 : public HGraphVisitor {
149734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public:
150734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen)
151734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      : HGraphVisitor(graph), codegen_(codegen) {}
152734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
153734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define DECLARE_VISIT_INSTRUCTION(name, super)     \
154734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Visit##name(H##name* instr) OVERRIDE;
155734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
156734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
157734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION)
158734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
159734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#undef DECLARE_VISIT_INSTRUCTION
160734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
161734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void VisitInstruction(HInstruction* instruction) OVERRIDE {
162734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
163734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller               << " (id " << instruction->GetId() << ")";
164734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
165734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
166734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private:
167734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleBitwiseOperation(HBinaryOperation* instruction);
168734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleInvoke(HInvoke* invoke);
169734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleShift(HBinaryOperation* instruction);
170734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
171734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
172734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
173734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  CodeGeneratorX86* const codegen_;
174734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  InvokeDexCallingConventionVisitorX86 parameter_visitor_;
175734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
176734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86);
177734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
178734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
179734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass InstructionCodeGeneratorX86 : public HGraphVisitor {
180734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public:
181734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen);
182734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
183734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define DECLARE_VISIT_INSTRUCTION(name, super)     \
184734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Visit##name(H##name* instr) OVERRIDE;
185734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
186734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
187734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION)
188734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
189734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#undef DECLARE_VISIT_INSTRUCTION
190734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
191734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void VisitInstruction(HInstruction* instruction) OVERRIDE {
192734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
193734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller               << " (id " << instruction->GetId() << ")";
194734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
1955880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hall
196734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  X86Assembler* GetAssembler() const { return assembler_; }
197734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
198734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private:
199734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Generate code for the given suspend check. If not null, `successor`
200734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // is the block to branch to if the suspend check is not needed, and after
201734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // the suspend call.
202734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor);
203734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateClassInitializationCheck(SlowPathCode* slow_path, Register class_reg);
204734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleBitwiseOperation(HBinaryOperation* instruction);
205734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateDivRemIntegral(HBinaryOperation* instruction);
206734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void DivRemOneOrMinusOne(HBinaryOperation* instruction);
207734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void DivByPowerOfTwo(HDiv* instruction);
208734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
209734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateRemFP(HRem* rem);
210734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleShift(HBinaryOperation* instruction);
211734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateShlLong(const Location& loc, Register shifter);
212734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateShrLong(const Location& loc, Register shifter);
213734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateUShrLong(const Location& loc, Register shifter);
214734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateShlLong(const Location& loc, int shift);
215734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateShrLong(const Location& loc, int shift);
216734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateUShrLong(const Location& loc, int shift);
217734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateMemoryBarrier(MemBarrierKind kind);
218734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleFieldSet(HInstruction* instruction,
219734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                      const FieldInfo& field_info,
220734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                      bool value_can_be_null);
221734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
222734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Push value to FPU stack. `is_fp` specifies whether the value is floating point or not.
223734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // `is_wide` specifies whether it is long/double or not.
224734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void PushOntoFPStack(Location source, uint32_t temp_offset,
225734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                       uint32_t stack_adjustment, bool is_fp, bool is_wide);
226734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
227734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateImplicitNullCheck(HNullCheck* instruction);
228734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateExplicitNullCheck(HNullCheck* instruction);
229734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateTestAndBranch(HInstruction* instruction,
230734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                             size_t condition_input_index,
231734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                             Label* true_target,
232734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                             Label* false_target);
233734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateCompareTestAndBranch(HCondition* condition,
234734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                    Label* true_target,
235734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                    Label* false_target);
236734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateFPJumps(HCondition* cond, Label* true_label, Label* false_label);
237734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateLongComparesAndJumps(HCondition* cond, Label* true_label, Label* false_label);
238734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void HandleGoto(HInstruction* got, HBasicBlock* successor);
239734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
240734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  X86Assembler* const assembler_;
241734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  CodeGeneratorX86* const codegen_;
242734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
243734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86);
244734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
245734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
246734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass JumpTableRIPFixup;
247734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
248734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass CodeGeneratorX86 : public CodeGenerator {
249734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public:
250734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  CodeGeneratorX86(HGraph* graph,
251734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   const X86InstructionSetFeatures& isa_features,
252734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   const CompilerOptions& compiler_options,
253734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   OptimizingCompilerStats* stats = nullptr);
254734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  virtual ~CodeGeneratorX86() {}
255734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
256734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateFrameEntry() OVERRIDE;
257734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateFrameExit() OVERRIDE;
258734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Bind(HBasicBlock* block) OVERRIDE;
259734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE;
260734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void MoveConstant(Location destination, int32_t value) OVERRIDE;
261734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void MoveLocation(Location dst, Location src, Primitive::Type dst_type) OVERRIDE;
262734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void AddLocationAsTemp(Location location, LocationSummary* locations) OVERRIDE;
263734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
264734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
265734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
266734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
267734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
268734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
269734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Generate code to invoke a runtime entry point.
270734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void InvokeRuntime(QuickEntrypointEnum entrypoint,
271734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                     HInstruction* instruction,
272734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                     uint32_t dex_pc,
273734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                     SlowPathCode* slow_path) OVERRIDE;
274734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
275734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void InvokeRuntime(int32_t entry_point_offset,
276734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                     HInstruction* instruction,
277734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                     uint32_t dex_pc,
278734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                     SlowPathCode* slow_path);
279734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
280734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  size_t GetWordSize() const OVERRIDE {
281734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return kX86WordSize;
282734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
283734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
284734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  size_t GetFloatingPointSpillSlotSize() const OVERRIDE {
285734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // 8 bytes == 2 words for each spill.
286734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return 2 * kX86WordSize;
287734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
288734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
289734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  HGraphVisitor* GetLocationBuilder() OVERRIDE {
290734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return &location_builder_;
291734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
292734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
293734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  HGraphVisitor* GetInstructionVisitor() OVERRIDE {
294734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return &instruction_visitor_;
295734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
296734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
297734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  X86Assembler* GetAssembler() OVERRIDE {
298734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return &assembler_;
299734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
300734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
301734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  const X86Assembler& GetAssembler() const OVERRIDE {
302734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return assembler_;
303734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
304734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
305734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
306734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return GetLabelOf(block)->Position();
307734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
308734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
309734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void SetupBlockedRegisters(bool is_baseline) const OVERRIDE;
310734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
311734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE;
312734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
313734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
314734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
315734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
316734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
317734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
318734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Blocks all register pairs made out of blocked core registers.
319734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void UpdateBlockedPairRegisters() const;
320734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
321734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  ParallelMoveResolverX86* GetMoveResolver() OVERRIDE {
322734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return &move_resolver_;
323734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
324734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
325734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  InstructionSet GetInstructionSet() const OVERRIDE {
326734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return InstructionSet::kX86;
327734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
328734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
329734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Helper method to move a 32bits value between two locations.
330734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Move32(Location destination, Location source);
331734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Helper method to move a 64bits value between two locations.
332734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Move64(Location destination, Location source);
333734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
334734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Check if the desired_dispatch_info is supported. If it is, return it,
335734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // otherwise return a fall-back info that should be used instead.
336734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
337734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
338734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller      MethodReference target_method) OVERRIDE;
339734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
340734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Generate a call to a static or direct method.
341734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
342734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Generate a call to a virtual method.
343734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
344734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
345734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void MoveFromReturnRegister(Location trg, Primitive::Type type) OVERRIDE;
346734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
347734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Emit linker patches.
348734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patches) OVERRIDE;
349734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
350734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Emit a write barrier.
351734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void MarkGCCard(Register temp,
352734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  Register card,
353734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  Register object,
354734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  Register value,
355734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  bool value_can_be_null);
356734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
357734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Label* GetLabelOf(HBasicBlock* block) const {
358734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return CommonGetLabelOf<Label>(block_labels_, block);
359734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
360734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
361734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Initialize() OVERRIDE {
362734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    block_labels_ = CommonInitializeLabels<Label>();
363734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
364734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
365734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  bool NeedsTwoRegisters(Primitive::Type type) const OVERRIDE {
366734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return type == Primitive::kPrimLong;
367734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
368734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
369734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  bool ShouldSplitLongMoves() const OVERRIDE { return true; }
370734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
371734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Label* GetFrameEntryLabel() { return &frame_entry_label_; }
372734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
373734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  const X86InstructionSetFeatures& GetInstructionSetFeatures() const {
374734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return isa_features_;
375734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
376734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
377734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void SetMethodAddressOffset(int32_t offset) {
378734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    method_address_offset_ = offset;
379734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
380734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
381734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  int32_t GetMethodAddressOffset() const {
382734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return method_address_offset_;
383734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
384734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
385734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  int32_t ConstantAreaStart() const {
386734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return constant_area_start_;
387734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  }
388734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
389734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Address LiteralDoubleAddress(double v, Register reg);
390734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Address LiteralFloatAddress(float v, Register reg);
391734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Address LiteralInt32Address(int32_t v, Register reg);
392734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Address LiteralInt64Address(int64_t v, Register reg);
393734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
394734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Address LiteralCaseTable(HX86PackedSwitch* switch_instr, Register reg, Register value);
395734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
396734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void Finalize(CodeAllocator* allocator) OVERRIDE;
397734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
398734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Generate a read barrier for a heap reference within `instruction`.
399734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //
400734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // A read barrier for an object reference read from the heap is
401734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // implemented as a call to the artReadBarrierSlow runtime entry
402734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // point, which is passed the values in locations `ref`, `obj`, and
403734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // `offset`:
404734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //
405734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //   mirror::Object* artReadBarrierSlow(mirror::Object* ref,
406734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //                                      mirror::Object* obj,
407734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //                                      uint32_t offset);
408734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //
409734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // The `out` location contains the value returned by
410734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // artReadBarrierSlow.
411734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //
412b685c542836b93c99cd85053e07696406ea37adbJesse Hall  // When `index` is provided (i.e. for array accesses), the offset
413734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // value passed to artReadBarrierSlow is adjusted to take `index`
414734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // into account.
415734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateReadBarrier(HInstruction* instruction,
416734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           Location out,
417734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           Location ref,
418734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           Location obj,
419734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           uint32_t offset,
420734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           Location index = Location::NoLocation());
421734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
422734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // If read barriers are enabled, generate a read barrier for a heap reference.
423734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // If heap poisoning is enabled, also unpoison the reference in `out`.
424734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void MaybeGenerateReadBarrier(HInstruction* instruction,
425734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                Location out,
426734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                Location ref,
427734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                Location obj,
428734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                uint32_t offset,
429734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                Location index = Location::NoLocation());
430734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
4315880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hall  // Generate a read barrier for a GC root within `instruction`.
432734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //
433734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // A read barrier for an object reference GC root is implemented as
434734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // a call to the artReadBarrierForRootSlow runtime entry point,
435734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // which is passed the value in location `root`:
436734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //
437734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //   mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root);
438734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  //
439734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // The `out` location contains the value returned by
440734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // artReadBarrierForRootSlow.
441734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  void GenerateReadBarrierForRoot(HInstruction* instruction, Location out, Location root);
442734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
443734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private:
444734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp);
445734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
446734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  struct PcRelativeDexCacheAccessInfo {
447734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    PcRelativeDexCacheAccessInfo(const DexFile& dex_file, uint32_t element_off)
448734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        : target_dex_file(dex_file), element_offset(element_off), label() { }
449734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
450734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    const DexFile& target_dex_file;
451734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    uint32_t element_offset;
452734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // NOTE: Label is bound to the end of the instruction that has an embedded 32-bit offset.
453734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    Label label;
454734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  };
455734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
456734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Labels for each block that will be compiled.
457734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Label* block_labels_;  // Indexed by block id.
458734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  Label frame_entry_label_;
459734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  LocationsBuilderX86 location_builder_;
460734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  InstructionCodeGeneratorX86 instruction_visitor_;
461734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  ParallelMoveResolverX86 move_resolver_;
462734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  X86Assembler assembler_;
463734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  const X86InstructionSetFeatures& isa_features_;
464734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
465734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Method patch info. Using ArenaDeque<> which retains element addresses on push/emplace_back().
466734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  ArenaDeque<MethodPatchInfo<Label>> method_patches_;
467734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  ArenaDeque<MethodPatchInfo<Label>> relative_call_patches_;
468734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // PC-relative DexCache access info.
469734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  ArenaDeque<PcRelativeDexCacheAccessInfo> pc_relative_dex_cache_patches_;
470734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
471734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Offset to the start of the constant area in the assembled code.
472734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Used for fixups to the constant area.
473734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  int32_t constant_area_start_;
474734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
475734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // Fixups for jump tables that need to be patched after the constant table is generated.
476734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  ArenaVector<JumpTableRIPFixup*> fixups_to_jump_tables_;
477734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
478734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // If there is a HX86ComputeBaseMethodAddress instruction in the graph
479734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // (which shall be the sole instruction of this kind), subtracting this offset
480734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // from the value contained in the out register of this HX86ComputeBaseMethodAddress
481b685c542836b93c99cd85053e07696406ea37adbJesse Hall  // instruction gives the address of the start of this method.
482734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  int32_t method_address_offset_;
483734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
484734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // When we don't know the proper offset for the value, we use kDummy32BitOffset.
485734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  // The correct value will be inserted when processing Assembler fixups.
486734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  static constexpr int32_t kDummy32BitOffset = 256;
487734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
488734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller  DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86);
489734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
490734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
491734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}  // namespace x86
492734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}  // namespace art
493734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
494b685c542836b93c99cd85053e07696406ea37adbJesse Hall#endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
495b685c542836b93c99cd85053e07696406ea37adbJesse Hall