Add x86_64 support to the optimizing compiler.
Change-Id: I4462d9ae15be56c4a3dc1bd4d1c0c6548c1b94be
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
new file mode 100644
index 0000000..ac7ee9f
--- /dev/null
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -0,0 +1,161 @@
+/*
+ * 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_64_H_
+#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_64_H_
+
+#include "code_generator.h"
+#include "nodes.h"
+#include "utils/x86_64/assembler_x86_64.h"
+
+namespace art {
+namespace x86_64 {
+
+static constexpr size_t kX86_64WordSize = 8;
+
+static constexpr Register kParameterCoreRegisters[] = { RSI, RDX, RCX, R8, R9 };
+
+static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
+
+class InvokeDexCallingConvention : public CallingConvention<Register> {
+ public:
+ InvokeDexCallingConvention()
+ : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
+};
+
+class InvokeDexCallingConventionVisitor {
+ public:
+ InvokeDexCallingConventionVisitor() : gp_index_(0), stack_index_(0) {}
+
+ Location GetNextLocation(Primitive::Type type);
+
+ private:
+ InvokeDexCallingConvention calling_convention;
+ uint32_t gp_index_;
+ uint32_t stack_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
+};
+
+class CodeGeneratorX86_64;
+
+class LocationsBuilderX86_64 : public HGraphVisitor {
+ public:
+ LocationsBuilderX86_64(HGraph* graph, CodeGeneratorX86_64* 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:
+ CodeGeneratorX86_64* const codegen_;
+ InvokeDexCallingConventionVisitor parameter_visitor_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86_64);
+};
+
+class InstructionCodeGeneratorX86_64 : public HGraphVisitor {
+ public:
+ InstructionCodeGeneratorX86_64(HGraph* graph, CodeGeneratorX86_64* codegen);
+
+#define DECLARE_VISIT_INSTRUCTION(name) \
+ virtual void Visit##name(H##name* instr);
+
+ FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
+
+#undef DECLARE_VISIT_INSTRUCTION
+
+ void LoadCurrentMethod(CpuRegister reg);
+
+ X86_64Assembler* GetAssembler() const { return assembler_; }
+
+ private:
+ X86_64Assembler* const assembler_;
+ CodeGeneratorX86_64* const codegen_;
+
+ DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86_64);
+};
+
+class CodeGeneratorX86_64 : public CodeGenerator {
+ public:
+ explicit CodeGeneratorX86_64(HGraph* graph);
+ virtual ~CodeGeneratorX86_64() {}
+
+ virtual void ComputeFrameSize(size_t number_of_spill_slots) OVERRIDE;
+ 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 kX86_64WordSize;
+ }
+
+ virtual HGraphVisitor* GetLocationBuilder() OVERRIDE {
+ return &location_builder_;
+ }
+
+ virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE {
+ return &instruction_visitor_;
+ }
+
+ virtual X86_64Assembler* GetAssembler() OVERRIDE {
+ return &assembler_;
+ }
+
+ int32_t GetStackSlot(HLocal* local) const;
+ virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
+
+ virtual size_t GetNumberOfRegisters() const OVERRIDE {
+ return kNumberOfRegIds;
+ }
+
+ virtual size_t GetNumberOfCoreRegisters() const OVERRIDE {
+ return kNumberOfCpuRegisters;
+ }
+
+ virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE {
+ return kNumberOfFloatRegisters;
+ }
+
+ virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE;
+ virtual ManagedRegister AllocateFreeRegister(
+ Primitive::Type type, bool* blocked_registers) const OVERRIDE;
+ 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 value between two locations.
+ void Move(Location destination, Location source);
+
+ LocationsBuilderX86_64 location_builder_;
+ InstructionCodeGeneratorX86_64 instruction_visitor_;
+ X86_64Assembler assembler_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86_64);
+};
+
+} // namespace x86_64
+} // namespace art
+
+#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_64_H_