Line data Source code
1 : // Copyright 2013 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_COMPILER_BACKEND_CODE_GENERATOR_IMPL_H_
6 : #define V8_COMPILER_BACKEND_CODE_GENERATOR_IMPL_H_
7 :
8 : #include "src/compiler/backend/code-generator.h"
9 : #include "src/compiler/backend/instruction.h"
10 : #include "src/compiler/linkage.h"
11 : #include "src/compiler/opcodes.h"
12 : #include "src/macro-assembler.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 : namespace compiler {
17 :
18 : // Converts InstructionOperands from a given instruction to
19 : // architecture-specific
20 : // registers and operands after they have been assigned by the register
21 : // allocator.
22 : class InstructionOperandConverter {
23 : public:
24 : InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
25 108231745 : : gen_(gen), instr_(instr) {}
26 :
27 : // -- Instruction operand accesses with conversions --------------------------
28 :
29 : Register InputRegister(size_t index) {
30 : return ToRegister(instr_->InputAt(index));
31 : }
32 :
33 : FloatRegister InputFloatRegister(size_t index) {
34 : return ToFloatRegister(instr_->InputAt(index));
35 : }
36 :
37 : DoubleRegister InputDoubleRegister(size_t index) {
38 : return ToDoubleRegister(instr_->InputAt(index));
39 : }
40 :
41 : Simd128Register InputSimd128Register(size_t index) {
42 : return ToSimd128Register(instr_->InputAt(index));
43 : }
44 :
45 : double InputDouble(size_t index) { return ToDouble(instr_->InputAt(index)); }
46 :
47 : float InputFloat32(size_t index) { return ToFloat32(instr_->InputAt(index)); }
48 :
49 : int32_t InputInt32(size_t index) {
50 55228514 : return ToConstant(instr_->InputAt(index)).ToInt32();
51 : }
52 :
53 : uint32_t InputUint32(size_t index) {
54 : return bit_cast<uint32_t>(InputInt32(index));
55 : }
56 :
57 4 : int64_t InputInt64(size_t index) {
58 12 : return ToConstant(instr_->InputAt(index)).ToInt64();
59 : }
60 :
61 : int8_t InputInt8(size_t index) {
62 11038 : return static_cast<int8_t>(InputInt32(index));
63 : }
64 :
65 : int16_t InputInt16(size_t index) {
66 899 : return static_cast<int16_t>(InputInt32(index));
67 : }
68 :
69 : uint8_t InputInt3(size_t index) {
70 : return static_cast<uint8_t>(InputInt32(index) & 0x7);
71 : }
72 :
73 : uint8_t InputInt4(size_t index) {
74 : return static_cast<uint8_t>(InputInt32(index) & 0xF);
75 : }
76 :
77 : uint8_t InputInt5(size_t index) {
78 329144 : return static_cast<uint8_t>(InputInt32(index) & 0x1F);
79 : }
80 :
81 : uint8_t InputInt6(size_t index) {
82 707831 : return static_cast<uint8_t>(InputInt32(index) & 0x3F);
83 : }
84 :
85 : ExternalReference InputExternalReference(size_t index) {
86 24480 : return ToExternalReference(instr_->InputAt(index));
87 : }
88 :
89 : Handle<Code> InputCode(size_t index) {
90 4825177 : return ToCode(instr_->InputAt(index));
91 : }
92 :
93 : Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
94 :
95 : RpoNumber InputRpo(size_t index) {
96 : return ToRpoNumber(instr_->InputAt(index));
97 : }
98 :
99 : Register OutputRegister(size_t index = 0) {
100 : return ToRegister(instr_->OutputAt(index));
101 : }
102 :
103 : Register TempRegister(size_t index) {
104 : return ToRegister(instr_->TempAt(index));
105 : }
106 :
107 : FloatRegister OutputFloatRegister() {
108 : return ToFloatRegister(instr_->Output());
109 : }
110 :
111 : DoubleRegister OutputDoubleRegister() {
112 : return ToDoubleRegister(instr_->Output());
113 : }
114 :
115 : Simd128Register OutputSimd128Register() {
116 : return ToSimd128Register(instr_->Output());
117 : }
118 :
119 : // -- Conversions for operands -----------------------------------------------
120 :
121 : Label* ToLabel(InstructionOperand* op) {
122 : return gen_->GetLabel(ToRpoNumber(op));
123 : }
124 :
125 : RpoNumber ToRpoNumber(InstructionOperand* op) {
126 33017185 : return ToConstant(op).ToRpoNumber();
127 : }
128 :
129 : Register ToRegister(InstructionOperand* op) {
130 : return LocationOperand::cast(op)->GetRegister();
131 : }
132 :
133 : FloatRegister ToFloatRegister(InstructionOperand* op) {
134 : return LocationOperand::cast(op)->GetFloatRegister();
135 : }
136 :
137 : DoubleRegister ToDoubleRegister(InstructionOperand* op) {
138 : return LocationOperand::cast(op)->GetDoubleRegister();
139 : }
140 :
141 : Simd128Register ToSimd128Register(InstructionOperand* op) {
142 : return LocationOperand::cast(op)->GetSimd128Register();
143 : }
144 :
145 78399184 : Constant ToConstant(InstructionOperand* op) {
146 78399184 : if (op->IsImmediate()) {
147 58902484 : return gen_->instructions()->GetImmediate(ImmediateOperand::cast(op));
148 : }
149 19496700 : return gen_->instructions()->GetConstant(
150 : ConstantOperand::cast(op)->virtual_register());
151 : }
152 :
153 : double ToDouble(InstructionOperand* op) {
154 : return ToConstant(op).ToFloat64().value();
155 : }
156 :
157 : float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }
158 :
159 24480 : ExternalReference ToExternalReference(InstructionOperand* op) {
160 48960 : return ToConstant(op).ToExternalReference();
161 : }
162 :
163 4794111 : Handle<Code> ToCode(InstructionOperand* op) {
164 4794111 : return ToConstant(op).ToCode();
165 : }
166 :
167 : const Frame* frame() const { return gen_->frame(); }
168 : FrameAccessState* frame_access_state() const {
169 : return gen_->frame_access_state();
170 : }
171 : Isolate* isolate() const { return gen_->isolate(); }
172 : Linkage* linkage() const { return gen_->linkage(); }
173 :
174 : protected:
175 : CodeGenerator* gen_;
176 : Instruction* instr_;
177 : };
178 :
179 : // Eager deoptimization exit.
180 : class DeoptimizationExit : public ZoneObject {
181 : public:
182 : explicit DeoptimizationExit(int deoptimization_id, SourcePosition pos)
183 7113526 : : deoptimization_id_(deoptimization_id), pos_(pos) {}
184 :
185 : int deoptimization_id() const { return deoptimization_id_; }
186 3642961 : Label* label() { return &label_; }
187 : SourcePosition pos() const { return pos_; }
188 :
189 : private:
190 : int const deoptimization_id_;
191 : Label label_;
192 : SourcePosition const pos_;
193 : };
194 :
195 : // Generator for out-of-line code that is emitted after the main code is done.
196 0 : class OutOfLineCode : public ZoneObject {
197 : public:
198 : explicit OutOfLineCode(CodeGenerator* gen);
199 : virtual ~OutOfLineCode();
200 :
201 : virtual void Generate() = 0;
202 :
203 1076631 : Label* entry() { return &entry_; }
204 1359157 : Label* exit() { return &exit_; }
205 : const Frame* frame() const { return frame_; }
206 : TurboAssembler* tasm() { return tasm_; }
207 : OutOfLineCode* next() const { return next_; }
208 :
209 : private:
210 : Label entry_;
211 : Label exit_;
212 : const Frame* const frame_;
213 : TurboAssembler* const tasm_;
214 : OutOfLineCode* const next_;
215 : };
216 :
217 : inline bool HasCallDescriptorFlag(Instruction* instr,
218 : CallDescriptor::Flag flag) {
219 1721201 : return MiscField::decode(instr->opcode()) & flag;
220 : }
221 :
222 : } // namespace compiler
223 : } // namespace internal
224 : } // namespace v8
225 :
226 : #endif // V8_COMPILER_BACKEND_CODE_GENERATOR_IMPL_H_
|