code_generator_arm.h revision 8d486731559ba0c5e12c27b4a507181333702b7e
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_ARM_H_
18#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_
19
20#include "code_generator.h"
21#include "nodes.h"
22#include "parallel_move_resolver.h"
23#include "utils/arm/assembler_thumb2.h"
24
25namespace art {
26namespace arm {
27
28class CodeGeneratorARM;
29
30static constexpr size_t kArmWordSize = 4;
31
32static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 };
33static constexpr RegisterPair kParameterCorePairRegisters[] = { R1_R2, R2_R3 };
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 ParallelMoveResolverARM : public ParallelMoveResolver {
64 public:
65  ParallelMoveResolverARM(ArenaAllocator* allocator, CodeGeneratorARM* 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  ArmAssembler* GetAssembler() const;
74
75 private:
76  void Exchange(Register reg, int mem);
77  void Exchange(int mem1, int mem2);
78
79  CodeGeneratorARM* const codegen_;
80
81  DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverARM);
82};
83
84class LocationsBuilderARM : public HGraphVisitor {
85 public:
86  explicit LocationsBuilderARM(HGraph* graph, CodeGeneratorARM* codegen)
87      : HGraphVisitor(graph), codegen_(codegen) {}
88
89#define DECLARE_VISIT_INSTRUCTION(name)     \
90  virtual void Visit##name(H##name* instr);
91
92  FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
93
94#undef DECLARE_VISIT_INSTRUCTION
95
96 private:
97  CodeGeneratorARM* const codegen_;
98  InvokeDexCallingConventionVisitor parameter_visitor_;
99
100  DISALLOW_COPY_AND_ASSIGN(LocationsBuilderARM);
101};
102
103class InstructionCodeGeneratorARM : public HGraphVisitor {
104 public:
105  InstructionCodeGeneratorARM(HGraph* graph, CodeGeneratorARM* codegen);
106
107#define DECLARE_VISIT_INSTRUCTION(name)     \
108  virtual void Visit##name(H##name* instr);
109
110  FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
111
112#undef DECLARE_VISIT_INSTRUCTION
113
114  ArmAssembler* GetAssembler() const { return assembler_; }
115  void LoadCurrentMethod(Register reg);
116
117 private:
118  ArmAssembler* const assembler_;
119  CodeGeneratorARM* const codegen_;
120
121  DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorARM);
122};
123
124class CodeGeneratorARM : public CodeGenerator {
125 public:
126  explicit CodeGeneratorARM(HGraph* graph);
127  virtual ~CodeGeneratorARM() { }
128
129  virtual void GenerateFrameEntry() OVERRIDE;
130  virtual void GenerateFrameExit() OVERRIDE;
131  virtual void Bind(Label* label) OVERRIDE;
132  virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE;
133
134  virtual size_t GetWordSize() const OVERRIDE {
135    return kArmWordSize;
136  }
137
138  virtual size_t FrameEntrySpillSize() const OVERRIDE;
139
140  virtual HGraphVisitor* GetLocationBuilder() OVERRIDE {
141    return &location_builder_;
142  }
143
144  virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE {
145    return &instruction_visitor_;
146  }
147
148  virtual ArmAssembler* GetAssembler() OVERRIDE {
149    return &assembler_;
150  }
151
152  virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE;
153  virtual ManagedRegister AllocateFreeRegister(
154      Primitive::Type type, bool* blocked_registers) const OVERRIDE;
155  virtual size_t GetNumberOfRegisters() const OVERRIDE;
156
157  virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
158
159  virtual size_t GetNumberOfCoreRegisters() const OVERRIDE {
160    return kNumberOfCoreRegisters;
161  }
162
163  virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE {
164    return kNumberOfDRegisters;
165  }
166
167  virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
168  virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
169
170  ParallelMoveResolverARM* GetMoveResolver() {
171    return &move_resolver_;
172  }
173
174  virtual InstructionSet GetInstructionSet() const OVERRIDE {
175    return InstructionSet::kThumb2;
176  }
177
178 private:
179  // Helper method to move a 32bits value between two locations.
180  void Move32(Location destination, Location source);
181  // Helper method to move a 64bits value between two locations.
182  void Move64(Location destination, Location source);
183
184  LocationsBuilderARM location_builder_;
185  InstructionCodeGeneratorARM instruction_visitor_;
186  ParallelMoveResolverARM move_resolver_;
187  Thumb2Assembler assembler_;
188
189  DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM);
190};
191
192}  // namespace arm
193}  // namespace art
194
195#endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_
196