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_CODE_GENERATOR_IMPL_H_
6 : #define V8_COMPILER_CODE_GENERATOR_IMPL_H_
7 :
8 : #include "src/code-stubs.h"
9 : #include "src/compiler/code-generator.h"
10 : #include "src/compiler/instruction.h"
11 : #include "src/compiler/linkage.h"
12 : #include "src/compiler/opcodes.h"
13 : #include "src/macro-assembler.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 : namespace compiler {
18 :
19 : // Converts InstructionOperands from a given instruction to
20 : // architecture-specific
21 : // registers and operands after they have been assigned by the register
22 : // allocator.
23 : class InstructionOperandConverter {
24 : public:
25 : InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
26 72934363 : : gen_(gen), instr_(instr) {}
27 :
28 : // -- Instruction operand accesses with conversions --------------------------
29 :
30 : Register InputRegister(size_t index) {
31 13973132 : return ToRegister(instr_->InputAt(index));
32 : }
33 :
34 : FloatRegister InputFloatRegister(size_t index) {
35 : return ToFloatRegister(instr_->InputAt(index));
36 : }
37 :
38 : DoubleRegister InputDoubleRegister(size_t index) {
39 533258 : return ToDoubleRegister(instr_->InputAt(index));
40 : }
41 :
42 : Simd128Register InputSimd128Register(size_t index) {
43 5600 : return ToSimd128Register(instr_->InputAt(index));
44 : }
45 :
46 : double InputDouble(size_t index) { return ToDouble(instr_->InputAt(index)); }
47 :
48 : float InputFloat32(size_t index) { return ToFloat32(instr_->InputAt(index)); }
49 :
50 30755096 : int32_t InputInt32(size_t index) {
51 61510191 : return ToConstant(instr_->InputAt(index)).ToInt32();
52 : }
53 :
54 : uint32_t InputUint32(size_t index) {
55 254416 : return bit_cast<uint32_t>(InputInt32(index));
56 : }
57 :
58 : int64_t InputInt64(size_t index) {
59 : return ToConstant(instr_->InputAt(index)).ToInt64();
60 : }
61 :
62 : int8_t InputInt8(size_t index) {
63 6817 : return static_cast<int8_t>(InputInt32(index));
64 : }
65 :
66 : int16_t InputInt16(size_t index) {
67 239 : return static_cast<int16_t>(InputInt32(index));
68 : }
69 :
70 : uint8_t InputInt3(size_t index) {
71 : return static_cast<uint8_t>(InputInt32(index) & 0x7);
72 : }
73 :
74 : uint8_t InputInt4(size_t index) {
75 : return static_cast<uint8_t>(InputInt32(index) & 0xF);
76 : }
77 :
78 : uint8_t InputInt5(size_t index) {
79 51590 : return static_cast<uint8_t>(InputInt32(index) & 0x1F);
80 : }
81 :
82 : uint8_t InputInt6(size_t index) {
83 621585 : return static_cast<uint8_t>(InputInt32(index) & 0x3F);
84 : }
85 :
86 : ExternalReference InputExternalReference(size_t index) {
87 1624 : return ToExternalReference(instr_->InputAt(index));
88 : }
89 :
90 : Handle<HeapObject> InputHeapObject(size_t index) {
91 6700430 : return ToHeapObject(instr_->InputAt(index));
92 : }
93 :
94 : Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
95 :
96 10247771 : RpoNumber InputRpo(size_t index) {
97 30743312 : return ToRpoNumber(instr_->InputAt(index));
98 : }
99 :
100 : Register OutputRegister(size_t index = 0) {
101 216577 : return ToRegister(instr_->OutputAt(index));
102 : }
103 :
104 : Register TempRegister(size_t index) {
105 698379 : return ToRegister(instr_->TempAt(index));
106 : }
107 :
108 : FloatRegister OutputFloatRegister() {
109 : return ToFloatRegister(instr_->Output());
110 : }
111 :
112 : DoubleRegister OutputDoubleRegister() {
113 : return ToDoubleRegister(instr_->Output());
114 : }
115 :
116 : Simd128Register OutputSimd128Register() {
117 : return ToSimd128Register(instr_->Output());
118 : }
119 :
120 : // -- Conversions for operands -----------------------------------------------
121 :
122 : Label* ToLabel(InstructionOperand* op) {
123 : return gen_->GetLabel(ToRpoNumber(op));
124 : }
125 :
126 10247771 : RpoNumber ToRpoNumber(InstructionOperand* op) {
127 20495541 : return ToConstant(op).ToRpoNumber();
128 : }
129 :
130 : Register ToRegister(InstructionOperand* op) {
131 : return LocationOperand::cast(op)->GetRegister();
132 : }
133 :
134 : FloatRegister ToFloatRegister(InstructionOperand* op) {
135 : return LocationOperand::cast(op)->GetFloatRegister();
136 : }
137 :
138 : DoubleRegister ToDoubleRegister(InstructionOperand* op) {
139 : return LocationOperand::cast(op)->GetDoubleRegister();
140 : }
141 :
142 : Simd128Register ToSimd128Register(InstructionOperand* op) {
143 : return LocationOperand::cast(op)->GetSimd128Register();
144 : }
145 :
146 53352330 : Constant ToConstant(InstructionOperand* op) {
147 53352330 : if (op->IsImmediate()) {
148 53352330 : return gen_->code()->GetImmediate(ImmediateOperand::cast(op));
149 : }
150 : return gen_->code()->GetConstant(
151 12174994 : ConstantOperand::cast(op)->virtual_register());
152 : }
153 :
154 : double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
155 :
156 : float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }
157 :
158 1624 : ExternalReference ToExternalReference(InstructionOperand* op) {
159 3248 : return ToConstant(op).ToExternalReference();
160 : }
161 :
162 3350214 : Handle<HeapObject> ToHeapObject(InstructionOperand* op) {
163 3350214 : return ToConstant(op).ToHeapObject();
164 : }
165 :
166 : const Frame* frame() const { return gen_->frame(); }
167 : FrameAccessState* frame_access_state() const {
168 9269799 : return gen_->frame_access_state();
169 : }
170 : Isolate* isolate() const { return gen_->isolate(); }
171 : Linkage* linkage() const { return gen_->linkage(); }
172 :
173 : protected:
174 : CodeGenerator* gen_;
175 : Instruction* instr_;
176 : };
177 :
178 : // Eager deoptimization exit.
179 : class DeoptimizationExit : public ZoneObject {
180 : public:
181 : explicit DeoptimizationExit(int deoptimization_id, SourcePosition pos)
182 524800 : : deoptimization_id_(deoptimization_id), pos_(pos) {}
183 :
184 : int deoptimization_id() const { return deoptimization_id_; }
185 : Label* label() { return &label_; }
186 : SourcePosition pos() const { return pos_; }
187 :
188 : private:
189 : int const deoptimization_id_;
190 : Label label_;
191 : SourcePosition const pos_;
192 : };
193 :
194 : // Generator for out-of-line code that is emitted after the main code is done.
195 : class OutOfLineCode : public ZoneObject {
196 : public:
197 : explicit OutOfLineCode(CodeGenerator* gen);
198 : virtual ~OutOfLineCode();
199 :
200 : virtual void Generate() = 0;
201 :
202 : Label* entry() { return &entry_; }
203 : Label* exit() { return &exit_; }
204 : const Frame* frame() const { return frame_; }
205 361985 : Isolate* isolate() const { return masm()->isolate(); }
206 : MacroAssembler* masm() const { return masm_; }
207 : OutOfLineCode* next() const { return next_; }
208 :
209 : private:
210 : Label entry_;
211 : Label exit_;
212 : const Frame* const frame_;
213 : MacroAssembler* const masm_;
214 : OutOfLineCode* const next_;
215 : };
216 :
217 : } // namespace compiler
218 : } // namespace internal
219 : } // namespace v8
220 :
221 : #endif // V8_COMPILER_CODE_GENERATOR_IMPL_H
|