code_generator_x86_64.h revision e982f0b8e809cece6f460fa2d8df25873aa69de4
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_64_H_ 18#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_64_H_ 19 20#include "code_generator.h" 21#include "nodes.h" 22#include "parallel_move_resolver.h" 23#include "utils/x86_64/assembler_x86_64.h" 24 25namespace art { 26namespace x86_64 { 27 28static constexpr size_t kX86_64WordSize = 8; 29 30static constexpr Register kParameterCoreRegisters[] = { RSI, RDX, RCX, R8, R9 }; 31 32static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 33 34class InvokeDexCallingConvention : public CallingConvention<Register> { 35 public: 36 InvokeDexCallingConvention() 37 : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {} 38 39 private: 40 DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); 41}; 42 43class InvokeDexCallingConventionVisitor { 44 public: 45 InvokeDexCallingConventionVisitor() : gp_index_(0), stack_index_(0) {} 46 47 Location GetNextLocation(Primitive::Type type); 48 49 private: 50 InvokeDexCallingConvention calling_convention; 51 uint32_t gp_index_; 52 uint32_t stack_index_; 53 54 DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); 55}; 56 57class CodeGeneratorX86_64; 58 59class ParallelMoveResolverX86_64 : public ParallelMoveResolver { 60 public: 61 ParallelMoveResolverX86_64(ArenaAllocator* allocator, CodeGeneratorX86_64* codegen) 62 : ParallelMoveResolver(allocator), codegen_(codegen) {} 63 64 virtual void EmitMove(size_t index) OVERRIDE; 65 virtual void EmitSwap(size_t index) OVERRIDE; 66 virtual void SpillScratch(int reg) OVERRIDE; 67 virtual void RestoreScratch(int reg) OVERRIDE; 68 69 X86_64Assembler* GetAssembler() const; 70 71 private: 72 void Exchange32(CpuRegister reg, int mem); 73 void Exchange32(int mem1, int mem2); 74 void Exchange64(CpuRegister reg, int mem); 75 void Exchange64(int mem1, int mem2); 76 77 CodeGeneratorX86_64* const codegen_; 78 79 DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverX86_64); 80}; 81 82class LocationsBuilderX86_64 : public HGraphVisitor { 83 public: 84 LocationsBuilderX86_64(HGraph* graph, CodeGeneratorX86_64* codegen) 85 : HGraphVisitor(graph), codegen_(codegen) {} 86 87#define DECLARE_VISIT_INSTRUCTION(name) \ 88 virtual void Visit##name(H##name* instr); 89 90 FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 91 92#undef DECLARE_VISIT_INSTRUCTION 93 94 void HandleInvoke(HInvoke* invoke); 95 96 private: 97 CodeGeneratorX86_64* const codegen_; 98 InvokeDexCallingConventionVisitor parameter_visitor_; 99 100 DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86_64); 101}; 102 103class InstructionCodeGeneratorX86_64 : public HGraphVisitor { 104 public: 105 InstructionCodeGeneratorX86_64(HGraph* graph, CodeGeneratorX86_64* codegen); 106 107#define DECLARE_VISIT_INSTRUCTION(name) \ 108 virtual void Visit##name(H##name* instr); 109 110 FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 111 112#undef DECLARE_VISIT_INSTRUCTION 113 114 void LoadCurrentMethod(CpuRegister reg); 115 116 X86_64Assembler* GetAssembler() const { return assembler_; } 117 118 private: 119 X86_64Assembler* const assembler_; 120 CodeGeneratorX86_64* const codegen_; 121 122 DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86_64); 123}; 124 125class CodeGeneratorX86_64 : public CodeGenerator { 126 public: 127 explicit CodeGeneratorX86_64(HGraph* graph); 128 virtual ~CodeGeneratorX86_64() {} 129 130 virtual void GenerateFrameEntry() OVERRIDE; 131 virtual void GenerateFrameExit() OVERRIDE; 132 virtual void Bind(Label* label) OVERRIDE; 133 virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE; 134 135 virtual size_t GetWordSize() const OVERRIDE { 136 return kX86_64WordSize; 137 } 138 139 virtual size_t FrameEntrySpillSize() const OVERRIDE; 140 141 virtual HGraphVisitor* GetLocationBuilder() OVERRIDE { 142 return &location_builder_; 143 } 144 145 virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE { 146 return &instruction_visitor_; 147 } 148 149 virtual X86_64Assembler* GetAssembler() OVERRIDE { 150 return &assembler_; 151 } 152 153 ParallelMoveResolverX86_64* GetMoveResolver() { 154 return &move_resolver_; 155 } 156 157 virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; 158 159 virtual size_t GetNumberOfRegisters() const OVERRIDE { 160 return kNumberOfRegIds; 161 } 162 163 virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { 164 return kNumberOfCpuRegisters; 165 } 166 167 virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE { 168 return kNumberOfFloatRegisters; 169 } 170 171 virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE; 172 virtual ManagedRegister AllocateFreeRegister( 173 Primitive::Type type, bool* blocked_registers) const OVERRIDE; 174 virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; 175 virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; 176 177 virtual InstructionSet GetInstructionSet() const OVERRIDE { 178 return InstructionSet::kX86_64; 179 } 180 181 // Emit a write barrier. 182 void MarkGCCard(CpuRegister temp, CpuRegister card, CpuRegister object, CpuRegister value); 183 184 // Helper method to move a value between two locations. 185 void Move(Location destination, Location source); 186 187 private: 188 LocationsBuilderX86_64 location_builder_; 189 InstructionCodeGeneratorX86_64 instruction_visitor_; 190 ParallelMoveResolverX86_64 move_resolver_; 191 X86_64Assembler assembler_; 192 193 DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86_64); 194}; 195 196} // namespace x86_64 197} // namespace art 198 199#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_64_H_ 200