code_generator_x86.h revision 9aec02fc5df5518c16f1e5a9b6cb198a192db973
1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/*
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (C) 2014 The Android Open Source Project
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Licensed under the Apache License, Version 2.0 (the "License");
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * you may not use this file except in compliance with the License.
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * You may obtain a copy of the License at
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *      http://www.apache.org/licenses/LICENSE-2.0
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Unless required by applicable law or agreed to in writing, software
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distributed under the License is distributed on an "AS IS" BASIS,
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * See the License for the specific language governing permissions and
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * limitations under the License.
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "code_generator.h"
21e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "nodes.h"
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "parallel_move_resolver.h"
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "utils/x86/assembler_x86.h"
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langleynamespace art {
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langleynamespace x86 {
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley// Use a local definition to prevent copying mistakes.
29d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic constexpr size_t kX86WordSize = kX86PointerSize;
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyclass CodeGeneratorX86;
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyclass SlowPathCodeX86;
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX };
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
37ac6c5371f5e5beafc345f312a097c3ebd4766afaKenny Rootstatic constexpr XmmRegister kParameterFpuRegisters[] = { };
38ac6c5371f5e5beafc345f312a097c3ebd4766afaKenny Rootstatic constexpr size_t kParameterFpuRegistersLength = 0;
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyclass InvokeDexCallingConvention : public CallingConvention<Register, XmmRegister> {
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley public:
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  InvokeDexCallingConvention() : CallingConvention(
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      kParameterCoreRegisters,
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      kParameterCoreRegistersLength,
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      kParameterFpuRegisters,
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      kParameterFpuRegistersLength) {}
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  RegisterPair GetRegisterPairAt(size_t argument_index) {
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return kParameterCorePairRegisters[argument_index];
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley private:
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyclass InvokeDexCallingConventionVisitor {
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley public:
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  InvokeDexCallingConventionVisitor() : gp_index_(0) {}
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  Location GetNextLocation(Primitive::Type type);
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley private:
64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  InvokeDexCallingConvention calling_convention;
65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint32_t gp_index_;
66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyclass ParallelMoveResolverX86 : public ParallelMoveResolver {
71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley public:
72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ParallelMoveResolverX86(ArenaAllocator* allocator, CodeGeneratorX86* codegen)
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      : ParallelMoveResolver(allocator), codegen_(codegen) {}
74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void EmitMove(size_t index) OVERRIDE;
76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void EmitSwap(size_t index) OVERRIDE;
77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void SpillScratch(int reg) OVERRIDE;
78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void RestoreScratch(int reg) OVERRIDE;
79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  X86Assembler* GetAssembler() const;
81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley private:
83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Exchange(Register reg, int mem);
84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Exchange(int mem1, int mem2);
85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void MoveMemoryToMemory(int dst, int src);
86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  CodeGeneratorX86* const codegen_;
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverX86);
90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyclass LocationsBuilderX86 : public HGraphVisitor {
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley public:
94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen)
95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      : HGraphVisitor(graph), codegen_(codegen) {}
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define DECLARE_VISIT_INSTRUCTION(name, super)     \
98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Visit##name(H##name* instr) OVERRIDE;
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#undef DECLARE_VISIT_INSTRUCTION
103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley private:
105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void HandleBitwiseOperation(HBinaryOperation* instruction);
106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void HandleInvoke(HInvoke* invoke);
107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void HandleShift(HBinaryOperation* instruction);
108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  CodeGeneratorX86* const codegen_;
110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  InvokeDexCallingConventionVisitor parameter_visitor_;
111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86);
113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyclass InstructionCodeGeneratorX86 : public HGraphVisitor {
116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley public:
117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen);
118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define DECLARE_VISIT_INSTRUCTION(name, super)     \
120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Visit##name(H##name* instr) OVERRIDE;
121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#undef DECLARE_VISIT_INSTRUCTION
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  X86Assembler* GetAssembler() const { return assembler_; }
127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley private:
129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  // Generate code for the given suspend check. If not null, `successor`
130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  // is the block to branch to if the suspend check is not needed, and after
131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  // the suspend call.
132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor);
133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void GenerateClassInitializationCheck(SlowPathCodeX86* slow_path, Register class_reg);
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void HandleBitwiseOperation(HBinaryOperation* instruction);
135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void GenerateDivRemIntegral(HBinaryOperation* instruction);
136e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  void HandleShift(HBinaryOperation* instruction);
137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void GenerateShlLong(const Location& loc, Register shifter);
138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void GenerateShrLong(const Location& loc, Register shifter);
139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void GenerateUShrLong(const Location& loc, Register shifter);
140e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
141e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  X86Assembler* const assembler_;
142e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  CodeGeneratorX86* const codegen_;
143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86);
145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
147d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyclass CodeGeneratorX86 : public CodeGenerator {
148e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root public:
149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  explicit CodeGeneratorX86(HGraph* graph);
150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  virtual ~CodeGeneratorX86() {}
151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void GenerateFrameEntry() OVERRIDE;
153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void GenerateFrameExit() OVERRIDE;
154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Bind(HBasicBlock* block) OVERRIDE;
155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE;
156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t GetWordSize() const OVERRIDE {
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return kX86WordSize;
161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t FrameEntrySpillSize() const OVERRIDE;
164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  HGraphVisitor* GetLocationBuilder() OVERRIDE {
166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return &location_builder_;
167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  HGraphVisitor* GetInstructionVisitor() OVERRIDE {
170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return &instruction_visitor_;
171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
172b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
173b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  X86Assembler* GetAssembler() OVERRIDE {
174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return &assembler_;
1754139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  }
1764139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley
1774139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
1784139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    return GetLabelOf(block)->Position();
1794139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  }
180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void SetupBlockedRegisters() const OVERRIDE;
182e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
183e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE;
184e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
185e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
186e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
187e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
188e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
189e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
190e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Blocks all register pairs made out of blocked core registers.
191e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  void UpdateBlockedPairRegisters() const;
192e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ParallelMoveResolverX86* GetMoveResolver() OVERRIDE {
194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return &move_resolver_;
195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  InstructionSet GetInstructionSet() const OVERRIDE {
198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return InstructionSet::kX86;
199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  // Helper method to move a 32bits value between two locations.
202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Move32(Location destination, Location source);
203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  // Helper method to move a 64bits value between two locations.
204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Move64(Location destination, Location source);
205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  // Emit a write barrier.
207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void MarkGCCard(Register temp, Register card, Register object, Register value);
208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void LoadCurrentMethod(Register reg);
210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  Label* GetLabelOf(HBasicBlock* block) const {
212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return block_labels_.GetRawStorage() + block->GetBlockId();
213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  void Initialize() OVERRIDE {
216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    block_labels_.SetSize(GetGraph()->GetBlocks().Size());
217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley private:
220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  // Labels for each block that will be compiled.
221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  GrowableArray<Label> block_labels_;
222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  LocationsBuilderX86 location_builder_;
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  InstructionCodeGeneratorX86 instruction_visitor_;
224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ParallelMoveResolverX86 move_resolver_;
225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  X86Assembler assembler_;
226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86);
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}  // namespace x86
231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}  // namespace art
232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley