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 25 namespace art { 26 namespace arm { 27 28 class CodeGeneratorARM; 29 30 static constexpr size_t kArmWordSize = 4; 31 32 static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 }; 33 static constexpr RegisterPair kParameterCorePairRegisters[] = { R1_R2, R2_R3 }; 34 static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 35 36 class InvokeDexCallingConvention : public CallingConvention<Register> { 37 public: InvokeDexCallingConvention()38 InvokeDexCallingConvention() 39 : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {} 40 GetRegisterPairAt(size_t argument_index)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 50 class InvokeDexCallingConventionVisitor { 51 public: InvokeDexCallingConventionVisitor()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 63 class ParallelMoveResolverARM : public ParallelMoveResolver { 64 public: ParallelMoveResolverARM(ArenaAllocator * allocator,CodeGeneratorARM * codegen)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 84 class LocationsBuilderARM : public HGraphVisitor { 85 public: LocationsBuilderARM(HGraph * graph,CodeGeneratorARM * codegen)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_CONCRETE_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 103 class 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 FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)110 FOR_EACH_CONCRETE_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 124 class CodeGeneratorARM : public CodeGenerator { 125 public: 126 explicit CodeGeneratorARM(HGraph* graph); ~CodeGeneratorARM()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 GetWordSize()134 virtual size_t GetWordSize() const OVERRIDE { 135 return kArmWordSize; 136 } 137 138 virtual size_t FrameEntrySpillSize() const OVERRIDE; 139 GetLocationBuilder()140 virtual HGraphVisitor* GetLocationBuilder() OVERRIDE { 141 return &location_builder_; 142 } 143 GetInstructionVisitor()144 virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE { 145 return &instruction_visitor_; 146 } 147 GetAssembler()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 GetNumberOfCoreRegisters()159 virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { 160 return kNumberOfCoreRegisters; 161 } 162 GetNumberOfFloatingPointRegisters()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 GetMoveResolver()170 ParallelMoveResolverARM* GetMoveResolver() { 171 return &move_resolver_; 172 } 173 GetInstructionSet()174 virtual InstructionSet GetInstructionSet() const OVERRIDE { 175 return InstructionSet::kThumb2; 176 } 177 178 // Helper method to move a 32bits value between two locations. 179 void Move32(Location destination, Location source); 180 // Helper method to move a 64bits value between two locations. 181 void Move64(Location destination, Location source); 182 183 // Emit a write barrier. 184 void MarkGCCard(Register temp, Register card, Register object, Register value); 185 186 private: 187 LocationsBuilderARM location_builder_; 188 InstructionCodeGeneratorARM instruction_visitor_; 189 ParallelMoveResolverARM move_resolver_; 190 Thumb2Assembler assembler_; 191 192 DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM); 193 }; 194 195 } // namespace arm 196 } // namespace art 197 198 #endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_ 199