code_generator_x86.h revision a7aca370a7d62ca04a1e24423d90e8020d6f1a58
1d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray/*
2d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
3d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray *
4d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
5d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * you may not use this file except in compliance with the License.
6d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * You may obtain a copy of the License at
7d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray *
8d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
9d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray *
10d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software
11d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
12d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * See the License for the specific language governing permissions and
14d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * limitations under the License.
15d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray */
16d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
17d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
18d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
19d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
20d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "code_generator.h"
21d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "nodes.h"
22787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray#include "utils/x86/assembler_x86.h"
23d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
24d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffraynamespace art {
25d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffraynamespace x86 {
26d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
27707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffraystatic constexpr size_t kX86WordSize = 4;
28707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffray
2901bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffrayclass CodeGeneratorX86;
3001bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
31a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffraystatic constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
32a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffraystatic constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX };
33a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffraystatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
34a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
35a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffrayclass InvokeDexCallingConvention : public CallingConvention<Register> {
36a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray public:
37a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  InvokeDexCallingConvention()
38a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray      : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {}
39a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
40a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  RegisterPair GetRegisterPairAt(size_t argument_index) {
41a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray    DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
42a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray    return kParameterCorePairRegisters[argument_index];
43a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  }
44a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
45a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray private:
46a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
47a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray};
48a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
49a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffrayclass InvokeDexCallingConventionVisitor {
50a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray public:
51a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  InvokeDexCallingConventionVisitor() : gp_index_(0) {}
52a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
53a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  Location GetNextLocation(Primitive::Type type);
54a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
55a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray private:
56a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  InvokeDexCallingConvention calling_convention;
57a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  uint32_t gp_index_;
58a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
59a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
60a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray};
61a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
62bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffrayclass LocationsBuilderX86 : public HGraphVisitor {
63bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray public:
6401bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen)
6501bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray      : HGraphVisitor(graph), codegen_(codegen) {}
66bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray
67bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray#define DECLARE_VISIT_INSTRUCTION(name)     \
68bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  virtual void Visit##name(H##name* instr);
69bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray
70bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
71bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray
72bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray#undef DECLARE_VISIT_INSTRUCTION
73bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray
74bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray private:
7501bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  CodeGeneratorX86* const codegen_;
76a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray  InvokeDexCallingConventionVisitor parameter_visitor_;
7701bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
78bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86);
79bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray};
80bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray
81787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffrayclass InstructionCodeGeneratorX86 : public HGraphVisitor {
82d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public:
834a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen);
84d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
85d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#define DECLARE_VISIT_INSTRUCTION(name)     \
86d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  virtual void Visit##name(H##name* instr);
87d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
88d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
89d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
90d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#undef DECLARE_VISIT_INSTRUCTION
91d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
928ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  void LoadCurrentMethod(Register reg);
938ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray
944a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  X86Assembler* GetAssembler() const { return assembler_; }
95787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
96787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray private:
974a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  X86Assembler* const assembler_;
984a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  CodeGeneratorX86* const codegen_;
99787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
100787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86);
101787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray};
102787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
103787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffrayclass CodeGeneratorX86 : public CodeGenerator {
104787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray public:
105a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  explicit CodeGeneratorX86(HGraph* graph);
106787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  virtual ~CodeGeneratorX86() { }
107787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
108bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  virtual void GenerateFrameEntry() OVERRIDE;
109bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  virtual void GenerateFrameExit() OVERRIDE;
110bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  virtual void Bind(Label* label) OVERRIDE;
1114a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE;
112bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray
113707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffray  virtual size_t GetWordSize() const OVERRIDE {
114707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffray    return kX86WordSize;
115707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffray  }
116707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffray
117bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  virtual HGraphVisitor* GetLocationBuilder() OVERRIDE {
118bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray    return &location_builder_;
119bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  }
120bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray
121787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE {
122787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray    return &instruction_visitor_;
123787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  }
124787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
125787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  virtual X86Assembler* GetAssembler() OVERRIDE {
126787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray    return &assembler_;
127787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  }
128787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
129a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  virtual size_t GetNumberOfRegisters() const OVERRIDE;
130a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE;
131a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  virtual ManagedRegister AllocateFreeRegister(
132a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray      Primitive::Type type, bool* blocked_registers) const OVERRIDE;
133a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray
1344a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  int32_t GetStackSlot(HLocal* local) const;
135a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
1364a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray
137d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray private:
13801bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  // Helper method to move a 32bits value between two locations.
13901bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  void Move32(Location destination, Location source);
14001bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  // Helper method to move a 64bits value between two locations.
14101bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  void Move64(Location destination, Location source);
14201bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
143bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  LocationsBuilderX86 location_builder_;
144787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  InstructionCodeGeneratorX86 instruction_visitor_;
145787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  X86Assembler assembler_;
146d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
147d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86);
148d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray};
149d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
150d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}  // namespace x86
151d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}  // namespace art
152d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
153d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_
154