blob: adb840069cc9f369637acc58c502af5f25446092 [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 Bernierd0a1eb72015-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 Bernierd0a1eb72015-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 Bernierd0a1eb72015-03-24 16:35:39 -040028 // -- Instruction operand accesses with conversions --------------------------
29
Ben Murdoch4a90d5f2016-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 Murdoch4a90d5f2016-03-22 12:00:34 +000034 DoubleRegister InputDoubleRegister(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 return ToDoubleRegister(instr_->InputAt(index));
36 }
37
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 double InputDouble(size_t index) { return ToDouble(instr_->InputAt(index)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 float InputFloat32(size_t index) { return ToFloat32(instr_->InputAt(index)); }
41
42 int32_t InputInt32(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043 return ToConstant(instr_->InputAt(index)).ToInt32();
44 }
45
Ben Murdochc5610432016-08-08 18:44:38 +010046 uint32_t InputUint32(size_t index) {
47 return bit_cast<uint32_t>(InputInt32(index));
48 }
49
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050 int64_t InputInt64(size_t index) {
51 return ToConstant(instr_->InputAt(index)).ToInt64();
52 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054 int8_t InputInt8(size_t index) {
55 return static_cast<int8_t>(InputInt32(index));
56 }
57
58 int16_t InputInt16(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 return static_cast<int16_t>(InputInt32(index));
60 }
61
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 uint8_t InputInt5(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063 return static_cast<uint8_t>(InputInt32(index) & 0x1F);
64 }
65
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000066 uint8_t InputInt6(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067 return static_cast<uint8_t>(InputInt32(index) & 0x3F);
68 }
69
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 ExternalReference InputExternalReference(size_t index) {
71 return ToExternalReference(instr_->InputAt(index));
72 }
73
74 Handle<HeapObject> InputHeapObject(size_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075 return ToHeapObject(instr_->InputAt(index));
76 }
77
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078 Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 RpoNumber InputRpo(size_t index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040081 return ToRpoNumber(instr_->InputAt(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000082 }
83
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084 Register OutputRegister(size_t index = 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000085 return ToRegister(instr_->OutputAt(index));
86 }
87
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088 Register TempRegister(size_t index) {
89 return ToRegister(instr_->TempAt(index));
90 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040091
Ben Murdochb8a8cc12014-11-26 15:28:44 +000092 DoubleRegister OutputDoubleRegister() {
93 return ToDoubleRegister(instr_->Output());
94 }
95
Emily Bernierd0a1eb72015-03-24 16:35:39 -040096 // -- Conversions for operands -----------------------------------------------
97
98 Label* ToLabel(InstructionOperand* op) {
99 return gen_->GetLabel(ToRpoNumber(op));
100 }
101
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 RpoNumber ToRpoNumber(InstructionOperand* op) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400103 return ToConstant(op).ToRpoNumber();
104 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105
106 Register ToRegister(InstructionOperand* op) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 return LocationOperand::cast(op)->GetRegister();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000108 }
109
110 DoubleRegister ToDoubleRegister(InstructionOperand* op) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000111 return LocationOperand::cast(op)->GetDoubleRegister();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112 }
113
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400114 Constant ToConstant(InstructionOperand* op) {
115 if (op->IsImmediate()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116 return gen_->code()->GetImmediate(ImmediateOperand::cast(op));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 return gen_->code()->GetConstant(
119 ConstantOperand::cast(op)->virtual_register());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 }
121
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400122 double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124 float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }
125
126 ExternalReference ToExternalReference(InstructionOperand* op) {
127 return ToConstant(op).ToExternalReference();
128 }
129
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400130 Handle<HeapObject> ToHeapObject(InstructionOperand* op) {
131 return ToConstant(op).ToHeapObject();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132 }
133
Ben Murdochc5610432016-08-08 18:44:38 +0100134 const Frame* frame() const { return gen_->frame(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135 FrameAccessState* frame_access_state() const {
136 return gen_->frame_access_state();
137 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000138 Isolate* isolate() const { return gen_->isolate(); }
139 Linkage* linkage() const { return gen_->linkage(); }
140
141 protected:
142 CodeGenerator* gen_;
143 Instruction* instr_;
144};
145
Ben Murdochda12d292016-06-02 14:46:10 +0100146// Eager deoptimization exit.
147class DeoptimizationExit : public ZoneObject {
148 public:
149 explicit DeoptimizationExit(int deoptimization_id)
150 : deoptimization_id_(deoptimization_id) {}
151
152 int deoptimization_id() const { return deoptimization_id_; }
153 Label* label() { return &label_; }
154
155 private:
156 int const deoptimization_id_;
157 Label label_;
158};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000159
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400160// Generator for out-of-line code that is emitted after the main code is done.
161class OutOfLineCode : public ZoneObject {
162 public:
163 explicit OutOfLineCode(CodeGenerator* gen);
164 virtual ~OutOfLineCode();
165
166 virtual void Generate() = 0;
167
168 Label* entry() { return &entry_; }
169 Label* exit() { return &exit_; }
Ben Murdochc5610432016-08-08 18:44:38 +0100170 const Frame* frame() const { return frame_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000171 Isolate* isolate() const { return masm()->isolate(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400172 MacroAssembler* masm() const { return masm_; }
173 OutOfLineCode* next() const { return next_; }
174
175 private:
176 Label entry_;
177 Label exit_;
Ben Murdochc5610432016-08-08 18:44:38 +0100178 const Frame* const frame_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400179 MacroAssembler* const masm_;
180 OutOfLineCode* const next_;
181};
182
183
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000184// TODO(dcarney): generify this on bleeding_edge and replace this call
185// when merged.
186static inline void FinishCode(MacroAssembler* masm) {
187#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
188 masm->CheckConstPool(true, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189#elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
190 masm->ud2();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191#endif
192}
193
194} // namespace compiler
195} // namespace internal
196} // namespace v8
197
198#endif // V8_COMPILER_CODE_GENERATOR_IMPL_H