code_generator_x86_64.h revision 9cf35523764d829ae0470dae2d5dd99be469c841
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 "utils/x86_64/assembler_x86_64.h" 23 24namespace art { 25namespace x86_64 { 26 27static constexpr size_t kX86_64WordSize = 8; 28 29static constexpr Register kParameterCoreRegisters[] = { RSI, RDX, RCX, R8, R9 }; 30 31static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 32 33class InvokeDexCallingConvention : public CallingConvention<Register> { 34 public: 35 InvokeDexCallingConvention() 36 : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {} 37 38 private: 39 DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); 40}; 41 42class InvokeDexCallingConventionVisitor { 43 public: 44 InvokeDexCallingConventionVisitor() : gp_index_(0), stack_index_(0) {} 45 46 Location GetNextLocation(Primitive::Type type); 47 48 private: 49 InvokeDexCallingConvention calling_convention; 50 uint32_t gp_index_; 51 uint32_t stack_index_; 52 53 DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); 54}; 55 56class CodeGeneratorX86_64; 57 58class LocationsBuilderX86_64 : public HGraphVisitor { 59 public: 60 LocationsBuilderX86_64(HGraph* graph, CodeGeneratorX86_64* codegen) 61 : HGraphVisitor(graph), codegen_(codegen) {} 62 63#define DECLARE_VISIT_INSTRUCTION(name) \ 64 virtual void Visit##name(H##name* instr); 65 66 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 67 68#undef DECLARE_VISIT_INSTRUCTION 69 70 private: 71 CodeGeneratorX86_64* const codegen_; 72 InvokeDexCallingConventionVisitor parameter_visitor_; 73 74 DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86_64); 75}; 76 77class InstructionCodeGeneratorX86_64 : public HGraphVisitor { 78 public: 79 InstructionCodeGeneratorX86_64(HGraph* graph, CodeGeneratorX86_64* codegen); 80 81#define DECLARE_VISIT_INSTRUCTION(name) \ 82 virtual void Visit##name(H##name* instr); 83 84 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 85 86#undef DECLARE_VISIT_INSTRUCTION 87 88 void LoadCurrentMethod(CpuRegister reg); 89 90 X86_64Assembler* GetAssembler() const { return assembler_; } 91 92 private: 93 X86_64Assembler* const assembler_; 94 CodeGeneratorX86_64* const codegen_; 95 96 DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86_64); 97}; 98 99class CodeGeneratorX86_64 : public CodeGenerator { 100 public: 101 explicit CodeGeneratorX86_64(HGraph* graph); 102 virtual ~CodeGeneratorX86_64() {} 103 104 virtual void ComputeFrameSize(size_t number_of_spill_slots) OVERRIDE; 105 virtual void GenerateFrameEntry() OVERRIDE; 106 virtual void GenerateFrameExit() OVERRIDE; 107 virtual void Bind(Label* label) OVERRIDE; 108 virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE; 109 110 virtual size_t GetWordSize() const OVERRIDE { 111 return kX86_64WordSize; 112 } 113 114 virtual HGraphVisitor* GetLocationBuilder() OVERRIDE { 115 return &location_builder_; 116 } 117 118 virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE { 119 return &instruction_visitor_; 120 } 121 122 virtual X86_64Assembler* GetAssembler() OVERRIDE { 123 return &assembler_; 124 } 125 126 int32_t GetStackSlot(HLocal* local) const; 127 virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; 128 129 virtual size_t GetNumberOfRegisters() const OVERRIDE { 130 return kNumberOfRegIds; 131 } 132 133 virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { 134 return kNumberOfCpuRegisters; 135 } 136 137 virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE { 138 return kNumberOfFloatRegisters; 139 } 140 141 virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE; 142 virtual ManagedRegister AllocateFreeRegister( 143 Primitive::Type type, bool* blocked_registers) const OVERRIDE; 144 virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; 145 virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; 146 147 private: 148 // Helper method to move a value between two locations. 149 void Move(Location destination, Location source); 150 151 LocationsBuilderX86_64 location_builder_; 152 InstructionCodeGeneratorX86_64 instruction_visitor_; 153 X86_64Assembler assembler_; 154 155 DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86_64); 156}; 157 158} // namespace x86_64 159} // namespace art 160 161#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_64_H_ 162