201 lines
5.9 KiB
C++
201 lines
5.9 KiB
C++
/*
|
|
* 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_X86_H_
|
|
#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
|
|
|
|
#include "code_generator.h"
|
|
#include "nodes.h"
|
|
#include "parallel_move_resolver.h"
|
|
#include "utils/x86/assembler_x86.h"
|
|
|
|
namespace art {
|
|
namespace x86 {
|
|
|
|
static constexpr size_t kX86WordSize = 4;
|
|
|
|
class CodeGeneratorX86;
|
|
|
|
static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
|
|
static constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX };
|
|
static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
|
|
|
|
class InvokeDexCallingConvention : public CallingConvention<Register> {
|
|
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 ParallelMoveResolverX86 : public ParallelMoveResolver {
|
|
public:
|
|
ParallelMoveResolverX86(ArenaAllocator* allocator, CodeGeneratorX86* codegen)
|
|
: ParallelMoveResolver(allocator), codegen_(codegen) {}
|
|
|
|
virtual void EmitMove(size_t index) OVERRIDE;
|
|
virtual void EmitSwap(size_t index) OVERRIDE;
|
|
virtual void SpillScratch(int reg) OVERRIDE;
|
|
virtual void RestoreScratch(int reg) OVERRIDE;
|
|
|
|
X86Assembler* GetAssembler() const;
|
|
|
|
private:
|
|
void Exchange(Register reg, int mem);
|
|
void Exchange(int mem1, int mem2);
|
|
void MoveMemoryToMemory(int dst, int src);
|
|
|
|
CodeGeneratorX86* const codegen_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverX86);
|
|
};
|
|
|
|
class LocationsBuilderX86 : public HGraphVisitor {
|
|
public:
|
|
LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen)
|
|
: HGraphVisitor(graph), codegen_(codegen) {}
|
|
|
|
#define DECLARE_VISIT_INSTRUCTION(name) \
|
|
virtual void Visit##name(H##name* instr);
|
|
|
|
FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
|
|
|
|
#undef DECLARE_VISIT_INSTRUCTION
|
|
|
|
private:
|
|
CodeGeneratorX86* const codegen_;
|
|
InvokeDexCallingConventionVisitor parameter_visitor_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86);
|
|
};
|
|
|
|
class InstructionCodeGeneratorX86 : public HGraphVisitor {
|
|
public:
|
|
InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen);
|
|
|
|
#define DECLARE_VISIT_INSTRUCTION(name) \
|
|
virtual void Visit##name(H##name* instr);
|
|
|
|
FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
|
|
|
|
#undef DECLARE_VISIT_INSTRUCTION
|
|
|
|
void LoadCurrentMethod(Register reg);
|
|
|
|
X86Assembler* GetAssembler() const { return assembler_; }
|
|
|
|
private:
|
|
X86Assembler* const assembler_;
|
|
CodeGeneratorX86* const codegen_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86);
|
|
};
|
|
|
|
class CodeGeneratorX86 : public CodeGenerator {
|
|
public:
|
|
explicit CodeGeneratorX86(HGraph* graph);
|
|
virtual ~CodeGeneratorX86() {}
|
|
|
|
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 kX86WordSize;
|
|
}
|
|
|
|
virtual size_t FrameEntrySpillSize() const OVERRIDE;
|
|
|
|
virtual HGraphVisitor* GetLocationBuilder() OVERRIDE {
|
|
return &location_builder_;
|
|
}
|
|
|
|
virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE {
|
|
return &instruction_visitor_;
|
|
}
|
|
|
|
virtual X86Assembler* GetAssembler() OVERRIDE {
|
|
return &assembler_;
|
|
}
|
|
|
|
virtual size_t GetNumberOfRegisters() const OVERRIDE;
|
|
virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE;
|
|
virtual ManagedRegister AllocateFreeRegister(
|
|
Primitive::Type type, bool* blocked_registers) const OVERRIDE;
|
|
|
|
virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
|
|
|
|
virtual size_t GetNumberOfCoreRegisters() const OVERRIDE {
|
|
return kNumberOfCpuRegisters;
|
|
}
|
|
|
|
virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE {
|
|
return kNumberOfXmmRegisters;
|
|
}
|
|
|
|
virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
|
|
virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
|
|
|
|
ParallelMoveResolverX86* GetMoveResolver() {
|
|
return &move_resolver_;
|
|
}
|
|
|
|
virtual InstructionSet GetInstructionSet() const OVERRIDE {
|
|
return InstructionSet::kX86;
|
|
}
|
|
|
|
// 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);
|
|
|
|
// Emit a write barrier.
|
|
void MarkGCCard(Register temp, Register card, Register object, Register value);
|
|
|
|
private:
|
|
LocationsBuilderX86 location_builder_;
|
|
InstructionCodeGeneratorX86 instruction_visitor_;
|
|
ParallelMoveResolverX86 move_resolver_;
|
|
X86Assembler assembler_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86);
|
|
};
|
|
|
|
} // namespace x86
|
|
} // namespace art
|
|
|
|
#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
|