/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_ #define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_ #include "code_generator.h" #include "nodes.h" #include "utils/arm/assembler_arm32.h" namespace art { namespace arm { class CodeGeneratorARM; static constexpr size_t kArmWordSize = 4; static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 }; static constexpr RegisterPair kParameterCorePairRegisters[] = { R1_R2, R2_R3 }; static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); class InvokeDexCallingConvention : public CallingConvention { public: InvokeDexCallingConvention() : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {} RegisterPair GetRegisterPairAt(size_t argument_index) { DCHECK_LT(argument_index + 1, GetNumberOfRegisters()); return kParameterCorePairRegisters[argument_index]; } private: DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); }; class InvokeDexCallingConventionVisitor { public: InvokeDexCallingConventionVisitor() : gp_index_(0) {} Location GetNextLocation(Primitive::Type type); private: InvokeDexCallingConvention calling_convention; uint32_t gp_index_; DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); }; class LocationsBuilderARM : public HGraphVisitor { public: explicit LocationsBuilderARM(HGraph* graph, CodeGeneratorARM* codegen) : HGraphVisitor(graph), codegen_(codegen) {} #define DECLARE_VISIT_INSTRUCTION(name) \ virtual void Visit##name(H##name* instr); FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) #undef DECLARE_VISIT_INSTRUCTION private: CodeGeneratorARM* const codegen_; InvokeDexCallingConventionVisitor parameter_visitor_; DISALLOW_COPY_AND_ASSIGN(LocationsBuilderARM); }; class InstructionCodeGeneratorARM : public HGraphVisitor { public: InstructionCodeGeneratorARM(HGraph* graph, CodeGeneratorARM* codegen); #define DECLARE_VISIT_INSTRUCTION(name) \ virtual void Visit##name(H##name* instr); FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) #undef DECLARE_VISIT_INSTRUCTION ArmAssembler* GetAssembler() const { return assembler_; } void LoadCurrentMethod(Register reg); private: ArmAssembler* const assembler_; CodeGeneratorARM* const codegen_; DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorARM); }; class CodeGeneratorARM : public CodeGenerator { public: explicit CodeGeneratorARM(HGraph* graph); virtual ~CodeGeneratorARM() { } virtual void GenerateFrameEntry() OVERRIDE; virtual void GenerateFrameExit() OVERRIDE; virtual void Bind(Label* label) OVERRIDE; virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE; virtual size_t GetWordSize() const OVERRIDE { return kArmWordSize; } virtual HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; } virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE { return &instruction_visitor_; } virtual ArmAssembler* GetAssembler() OVERRIDE { return &assembler_; } virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE; virtual ManagedRegister AllocateFreeRegister( Primitive::Type type, bool* blocked_registers) const OVERRIDE; virtual size_t GetNumberOfRegisters() const OVERRIDE; int32_t GetStackSlot(HLocal* local) const; virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { return kNumberOfCoreRegisters; } virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE { return kNumberOfDRegisters; } virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; private: // Helper method to move a 32bits value between two locations. void Move32(Location destination, Location source); // Helper method to move a 64bits value between two locations. void Move64(Location destination, Location source); LocationsBuilderARM location_builder_; InstructionCodeGeneratorARM instruction_visitor_; Arm32Assembler assembler_; DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM); }; } // namespace arm } // namespace art #endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_