code_generator_x86.h revision f12feb8e0e857f2832545b3f28d31bad5a9d3903
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
18#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
19
20#include "code_generator.h"
21#include "nodes.h"
22#include "parallel_move_resolver.h"
23#include "utils/x86/assembler_x86.h"
24
25namespace art {
26namespace x86 {
27
28static constexpr size_t kX86WordSize = 4;
29
30class CodeGeneratorX86;
31
32static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
33static constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX };
34static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
35
36class InvokeDexCallingConvention : public CallingConvention<Register> {
37 public:
38  InvokeDexCallingConvention()
39      : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {}
40
41  RegisterPair GetRegisterPairAt(size_t argument_index) {
42    DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
43    return kParameterCorePairRegisters[argument_index];
44  }
45
46 private:
47  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
48};
49
50class InvokeDexCallingConventionVisitor {
51 public:
52  InvokeDexCallingConventionVisitor() : gp_index_(0) {}
53
54  Location GetNextLocation(Primitive::Type type);
55
56 private:
57  InvokeDexCallingConvention calling_convention;
58  uint32_t gp_index_;
59
60  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
61};
62
63class ParallelMoveResolverX86 : public ParallelMoveResolver {
64 public:
65  ParallelMoveResolverX86(ArenaAllocator* allocator, CodeGeneratorX86* codegen)
66      : ParallelMoveResolver(allocator), codegen_(codegen) {}
67
68  virtual void EmitMove(size_t index) OVERRIDE;
69  virtual void EmitSwap(size_t index) OVERRIDE;
70  virtual void SpillScratch(int reg) OVERRIDE;
71  virtual void RestoreScratch(int reg) OVERRIDE;
72
73  X86Assembler* GetAssembler() const;
74
75 private:
76  void Exchange(Register reg, int mem);
77  void Exchange(int mem1, int mem2);
78  void MoveMemoryToMemory(int dst, int src);
79
80  CodeGeneratorX86* const codegen_;
81
82  DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverX86);
83};
84
85class LocationsBuilderX86 : public HGraphVisitor {
86 public:
87  LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen)
88      : HGraphVisitor(graph), codegen_(codegen) {}
89
90#define DECLARE_VISIT_INSTRUCTION(name)     \
91  virtual void Visit##name(H##name* instr);
92
93  FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
94
95#undef DECLARE_VISIT_INSTRUCTION
96
97 private:
98  CodeGeneratorX86* const codegen_;
99  InvokeDexCallingConventionVisitor parameter_visitor_;
100
101  DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86);
102};
103
104class InstructionCodeGeneratorX86 : public HGraphVisitor {
105 public:
106  InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen);
107
108#define DECLARE_VISIT_INSTRUCTION(name)     \
109  virtual void Visit##name(H##name* instr);
110
111  FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
112
113#undef DECLARE_VISIT_INSTRUCTION
114
115  void LoadCurrentMethod(Register reg);
116
117  X86Assembler* GetAssembler() const { return assembler_; }
118
119 private:
120  X86Assembler* const assembler_;
121  CodeGeneratorX86* const codegen_;
122
123  DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86);
124};
125
126class CodeGeneratorX86 : public CodeGenerator {
127 public:
128  explicit CodeGeneratorX86(HGraph* graph);
129  virtual ~CodeGeneratorX86() {}
130
131  virtual void GenerateFrameEntry() OVERRIDE;
132  virtual void GenerateFrameExit() OVERRIDE;
133  virtual void Bind(Label* label) OVERRIDE;
134  virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE;
135
136  virtual size_t GetWordSize() const OVERRIDE {
137    return kX86WordSize;
138  }
139
140  virtual size_t FrameEntrySpillSize() const OVERRIDE;
141
142  virtual HGraphVisitor* GetLocationBuilder() OVERRIDE {
143    return &location_builder_;
144  }
145
146  virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE {
147    return &instruction_visitor_;
148  }
149
150  virtual X86Assembler* GetAssembler() OVERRIDE {
151    return &assembler_;
152  }
153
154  virtual size_t GetNumberOfRegisters() const OVERRIDE;
155  virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE;
156  virtual ManagedRegister AllocateFreeRegister(
157      Primitive::Type type, bool* blocked_registers) const OVERRIDE;
158
159  virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
160
161  virtual size_t GetNumberOfCoreRegisters() const OVERRIDE {
162    return kNumberOfCpuRegisters;
163  }
164
165  virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE {
166    return kNumberOfXmmRegisters;
167  }
168
169  virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
170  virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
171
172  ParallelMoveResolverX86* GetMoveResolver() {
173    return &move_resolver_;
174  }
175
176  virtual InstructionSet GetInstructionSet() const OVERRIDE {
177    return InstructionSet::kX86;
178  }
179
180 private:
181  // Helper method to move a 32bits value between two locations.
182  void Move32(Location destination, Location source);
183  // Helper method to move a 64bits value between two locations.
184  void Move64(Location destination, Location source);
185
186  LocationsBuilderX86 location_builder_;
187  InstructionCodeGeneratorX86 instruction_visitor_;
188  ParallelMoveResolverX86 move_resolver_;
189  X86Assembler assembler_;
190
191  DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86);
192};
193
194}  // namespace x86
195}  // namespace art
196
197#endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
198