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 25 namespace art { 26 namespace x86 { 27 28 static constexpr size_t kX86WordSize = 4; 29 30 class CodeGeneratorX86; 31 32 static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX }; 33 static constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX }; 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 ParallelMoveResolverX86 : public ParallelMoveResolver { 64 public: ParallelMoveResolverX86(ArenaAllocator * allocator,CodeGeneratorX86 * codegen)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 85 class LocationsBuilderX86 : public HGraphVisitor { 86 public: LocationsBuilderX86(HGraph * graph,CodeGeneratorX86 * codegen)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 104 class 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 GetAssembler()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 126 class CodeGeneratorX86 : public CodeGenerator { 127 public: 128 explicit CodeGeneratorX86(HGraph* graph); ~CodeGeneratorX86()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 GetWordSize()136 virtual size_t GetWordSize() const OVERRIDE { 137 return kX86WordSize; 138 } 139 140 virtual size_t FrameEntrySpillSize() const OVERRIDE; 141 GetLocationBuilder()142 virtual HGraphVisitor* GetLocationBuilder() OVERRIDE { 143 return &location_builder_; 144 } 145 GetInstructionVisitor()146 virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE { 147 return &instruction_visitor_; 148 } 149 GetAssembler()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 GetNumberOfCoreRegisters()161 virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { 162 return kNumberOfCpuRegisters; 163 } 164 GetNumberOfFloatingPointRegisters()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 GetMoveResolver()172 ParallelMoveResolverX86* GetMoveResolver() { 173 return &move_resolver_; 174 } 175 GetInstructionSet()176 virtual InstructionSet GetInstructionSet() const OVERRIDE { 177 return InstructionSet::kX86; 178 } 179 180 // Helper method to move a 32bits value between two locations. 181 void Move32(Location destination, Location source); 182 // Helper method to move a 64bits value between two locations. 183 void Move64(Location destination, Location source); 184 185 // Emit a write barrier. 186 void MarkGCCard(Register temp, Register card, Register object, Register value); 187 188 private: 189 LocationsBuilderX86 location_builder_; 190 InstructionCodeGeneratorX86 instruction_visitor_; 191 ParallelMoveResolverX86 move_resolver_; 192 X86Assembler assembler_; 193 194 DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86); 195 }; 196 197 } // namespace x86 198 } // namespace art 199 200 #endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_ 201