blob: 8bf3a9ea4e3bbc9a1801f284fa935b12b0eb8f47 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Emily Bernier958fae72015-03-24 16:35:39 -04008#include "src/code-stubs.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/compiler/code-generator.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/compiler/instruction.h"
11#include "src/compiler/linkage.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#include "src/compiler/opcodes.h"
Emily Bernier958fae72015-03-24 16:35:39 -040013#include "src/macro-assembler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014
15namespace v8 {
16namespace internal {
17namespace 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.
23class InstructionOperandConverter {
24 public:
25 InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
26 : gen_(gen), instr_(instr) {}
27
Emily Bernier958fae72015-03-24 16:35:39 -040028 // -- Instruction operand accesses with conversions --------------------------
29
Ben Murdoch014dc512016-03-22 12:00:34 +000030 Register InputRegister(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031 return ToRegister(instr_->InputAt(index));
32 }
33
Ben Murdoch13e2dad2016-09-16 13:49:30 +010034 FloatRegister InputFloatRegister(size_t index) {
35 return ToFloatRegister(instr_->InputAt(index));
36 }
37
Ben Murdoch014dc512016-03-22 12:00:34 +000038 DoubleRegister InputDoubleRegister(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039 return ToDoubleRegister(instr_->InputAt(index));
40 }
41
Ben Murdochf91f0612016-11-29 16:50:11 +000042 Simd128Register InputSimd128Register(size_t index) {
43 return ToSimd128Register(instr_->InputAt(index));
44 }
45
Ben Murdoch014dc512016-03-22 12:00:34 +000046 double InputDouble(size_t index) { return ToDouble(instr_->InputAt(index)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047
Ben Murdoch014dc512016-03-22 12:00:34 +000048 float InputFloat32(size_t index) { return ToFloat32(instr_->InputAt(index)); }
49
50 int32_t InputInt32(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051 return ToConstant(instr_->InputAt(index)).ToInt32();
52 }
53
Ben Murdochbcf72ee2016-08-08 18:44:38 +010054 uint32_t InputUint32(size_t index) {
55 return bit_cast<uint32_t>(InputInt32(index));
56 }
57
Ben Murdoch014dc512016-03-22 12:00:34 +000058 int64_t InputInt64(size_t index) {
59 return ToConstant(instr_->InputAt(index)).ToInt64();
60 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061
Ben Murdoch014dc512016-03-22 12:00:34 +000062 int8_t InputInt8(size_t index) {
63 return static_cast<int8_t>(InputInt32(index));
64 }
65
66 int16_t InputInt16(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067 return static_cast<int16_t>(InputInt32(index));
68 }
69
Ben Murdoch014dc512016-03-22 12:00:34 +000070 uint8_t InputInt5(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 return static_cast<uint8_t>(InputInt32(index) & 0x1F);
72 }
73
Ben Murdoch014dc512016-03-22 12:00:34 +000074 uint8_t InputInt6(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075 return static_cast<uint8_t>(InputInt32(index) & 0x3F);
76 }
77
Ben Murdoch014dc512016-03-22 12:00:34 +000078 ExternalReference InputExternalReference(size_t index) {
79 return ToExternalReference(instr_->InputAt(index));
80 }
81
82 Handle<HeapObject> InputHeapObject(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083 return ToHeapObject(instr_->InputAt(index));
84 }
85
Ben Murdoch014dc512016-03-22 12:00:34 +000086 Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087
Ben Murdoch014dc512016-03-22 12:00:34 +000088 RpoNumber InputRpo(size_t index) {
Emily Bernier958fae72015-03-24 16:35:39 -040089 return ToRpoNumber(instr_->InputAt(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090 }
91
Ben Murdoch014dc512016-03-22 12:00:34 +000092 Register OutputRegister(size_t index = 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093 return ToRegister(instr_->OutputAt(index));
94 }
95
Ben Murdoch014dc512016-03-22 12:00:34 +000096 Register TempRegister(size_t index) {
97 return ToRegister(instr_->TempAt(index));
98 }
Emily Bernier958fae72015-03-24 16:35:39 -040099
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100100 FloatRegister OutputFloatRegister() {
101 return ToFloatRegister(instr_->Output());
102 }
103
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000104 DoubleRegister OutputDoubleRegister() {
105 return ToDoubleRegister(instr_->Output());
106 }
107
Ben Murdochf91f0612016-11-29 16:50:11 +0000108 Simd128Register OutputSimd128Register() {
109 return ToSimd128Register(instr_->Output());
110 }
111
Emily Bernier958fae72015-03-24 16:35:39 -0400112 // -- Conversions for operands -----------------------------------------------
113
114 Label* ToLabel(InstructionOperand* op) {
115 return gen_->GetLabel(ToRpoNumber(op));
116 }
117
Ben Murdoch014dc512016-03-22 12:00:34 +0000118 RpoNumber ToRpoNumber(InstructionOperand* op) {
Emily Bernier958fae72015-03-24 16:35:39 -0400119 return ToConstant(op).ToRpoNumber();
120 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121
122 Register ToRegister(InstructionOperand* op) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000123 return LocationOperand::cast(op)->GetRegister();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124 }
125
Ben Murdochf91f0612016-11-29 16:50:11 +0000126 FloatRegister ToFloatRegister(InstructionOperand* op) {
127 return LocationOperand::cast(op)->GetFloatRegister();
128 }
129
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000130 DoubleRegister ToDoubleRegister(InstructionOperand* op) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000131 return LocationOperand::cast(op)->GetDoubleRegister();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132 }
133
Ben Murdochf91f0612016-11-29 16:50:11 +0000134 Simd128Register ToSimd128Register(InstructionOperand* op) {
135 return LocationOperand::cast(op)->GetSimd128Register();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100136 }
137
Emily Bernier958fae72015-03-24 16:35:39 -0400138 Constant ToConstant(InstructionOperand* op) {
139 if (op->IsImmediate()) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000140 return gen_->code()->GetImmediate(ImmediateOperand::cast(op));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000142 return gen_->code()->GetConstant(
143 ConstantOperand::cast(op)->virtual_register());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000144 }
145
Emily Bernier958fae72015-03-24 16:35:39 -0400146 double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147
Ben Murdoch014dc512016-03-22 12:00:34 +0000148 float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }
149
150 ExternalReference ToExternalReference(InstructionOperand* op) {
151 return ToConstant(op).ToExternalReference();
152 }
153
Emily Bernier958fae72015-03-24 16:35:39 -0400154 Handle<HeapObject> ToHeapObject(InstructionOperand* op) {
155 return ToConstant(op).ToHeapObject();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156 }
157
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100158 const Frame* frame() const { return gen_->frame(); }
Ben Murdoch014dc512016-03-22 12:00:34 +0000159 FrameAccessState* frame_access_state() const {
160 return gen_->frame_access_state();
161 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000162 Isolate* isolate() const { return gen_->isolate(); }
163 Linkage* linkage() const { return gen_->linkage(); }
164
165 protected:
166 CodeGenerator* gen_;
167 Instruction* instr_;
168};
169
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100170// Eager deoptimization exit.
171class DeoptimizationExit : public ZoneObject {
172 public:
Ben Murdochf3b273f2017-01-17 12:11:28 +0000173 explicit DeoptimizationExit(int deoptimization_id, SourcePosition pos)
174 : deoptimization_id_(deoptimization_id), pos_(pos) {}
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100175
176 int deoptimization_id() const { return deoptimization_id_; }
177 Label* label() { return &label_; }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000178 SourcePosition pos() const { return pos_; }
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100179
180 private:
181 int const deoptimization_id_;
182 Label label_;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000183 SourcePosition const pos_;
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100184};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185
Emily Bernier958fae72015-03-24 16:35:39 -0400186// Generator for out-of-line code that is emitted after the main code is done.
187class OutOfLineCode : public ZoneObject {
188 public:
189 explicit OutOfLineCode(CodeGenerator* gen);
190 virtual ~OutOfLineCode();
191
192 virtual void Generate() = 0;
193
194 Label* entry() { return &entry_; }
195 Label* exit() { return &exit_; }
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100196 const Frame* frame() const { return frame_; }
Ben Murdoch014dc512016-03-22 12:00:34 +0000197 Isolate* isolate() const { return masm()->isolate(); }
Emily Bernier958fae72015-03-24 16:35:39 -0400198 MacroAssembler* masm() const { return masm_; }
199 OutOfLineCode* next() const { return next_; }
200
201 private:
202 Label entry_;
203 Label exit_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100204 const Frame* const frame_;
Emily Bernier958fae72015-03-24 16:35:39 -0400205 MacroAssembler* const masm_;
206 OutOfLineCode* const next_;
207};
208
209
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210// TODO(dcarney): generify this on bleeding_edge and replace this call
211// when merged.
212static inline void FinishCode(MacroAssembler* masm) {
213#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
214 masm->CheckConstPool(true, false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000215#endif
216}
217
218} // namespace compiler
219} // namespace internal
220} // namespace v8
221
222#endif // V8_COMPILER_CODE_GENERATOR_IMPL_H