• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
InstructionOperandConverter(CodeGenerator * gen,Instruction * instr)25   InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
26       : gen_(gen), instr_(instr) {}
27 
28   // -- Instruction operand accesses with conversions --------------------------
29 
InputRegister(size_t index)30   Register InputRegister(size_t index) {
31     return ToRegister(instr_->InputAt(index));
32   }
33 
InputFloatRegister(size_t index)34   FloatRegister InputFloatRegister(size_t index) {
35     return ToFloatRegister(instr_->InputAt(index));
36   }
37 
InputDoubleRegister(size_t index)38   DoubleRegister InputDoubleRegister(size_t index) {
39     return ToDoubleRegister(instr_->InputAt(index));
40   }
41 
InputDouble(size_t index)42   double InputDouble(size_t index) { return ToDouble(instr_->InputAt(index)); }
43 
InputFloat32(size_t index)44   float InputFloat32(size_t index) { return ToFloat32(instr_->InputAt(index)); }
45 
InputInt32(size_t index)46   int32_t InputInt32(size_t index) {
47     return ToConstant(instr_->InputAt(index)).ToInt32();
48   }
49 
InputUint32(size_t index)50   uint32_t InputUint32(size_t index) {
51     return bit_cast<uint32_t>(InputInt32(index));
52   }
53 
InputInt64(size_t index)54   int64_t InputInt64(size_t index) {
55     return ToConstant(instr_->InputAt(index)).ToInt64();
56   }
57 
InputInt8(size_t index)58   int8_t InputInt8(size_t index) {
59     return static_cast<int8_t>(InputInt32(index));
60   }
61 
InputInt16(size_t index)62   int16_t InputInt16(size_t index) {
63     return static_cast<int16_t>(InputInt32(index));
64   }
65 
InputInt5(size_t index)66   uint8_t InputInt5(size_t index) {
67     return static_cast<uint8_t>(InputInt32(index) & 0x1F);
68   }
69 
InputInt6(size_t index)70   uint8_t InputInt6(size_t index) {
71     return static_cast<uint8_t>(InputInt32(index) & 0x3F);
72   }
73 
InputExternalReference(size_t index)74   ExternalReference InputExternalReference(size_t index) {
75     return ToExternalReference(instr_->InputAt(index));
76   }
77 
InputHeapObject(size_t index)78   Handle<HeapObject> InputHeapObject(size_t index) {
79     return ToHeapObject(instr_->InputAt(index));
80   }
81 
InputLabel(size_t index)82   Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
83 
InputRpo(size_t index)84   RpoNumber InputRpo(size_t index) {
85     return ToRpoNumber(instr_->InputAt(index));
86   }
87 
88   Register OutputRegister(size_t index = 0) {
89     return ToRegister(instr_->OutputAt(index));
90   }
91 
TempRegister(size_t index)92   Register TempRegister(size_t index) {
93     return ToRegister(instr_->TempAt(index));
94   }
95 
OutputFloatRegister()96   FloatRegister OutputFloatRegister() {
97     return ToFloatRegister(instr_->Output());
98   }
99 
OutputDoubleRegister()100   DoubleRegister OutputDoubleRegister() {
101     return ToDoubleRegister(instr_->Output());
102   }
103 
104   // -- Conversions for operands -----------------------------------------------
105 
ToLabel(InstructionOperand * op)106   Label* ToLabel(InstructionOperand* op) {
107     return gen_->GetLabel(ToRpoNumber(op));
108   }
109 
ToRpoNumber(InstructionOperand * op)110   RpoNumber ToRpoNumber(InstructionOperand* op) {
111     return ToConstant(op).ToRpoNumber();
112   }
113 
ToRegister(InstructionOperand * op)114   Register ToRegister(InstructionOperand* op) {
115     return LocationOperand::cast(op)->GetRegister();
116   }
117 
ToDoubleRegister(InstructionOperand * op)118   DoubleRegister ToDoubleRegister(InstructionOperand* op) {
119     return LocationOperand::cast(op)->GetDoubleRegister();
120   }
121 
ToFloatRegister(InstructionOperand * op)122   FloatRegister ToFloatRegister(InstructionOperand* op) {
123     return LocationOperand::cast(op)->GetFloatRegister();
124   }
125 
ToConstant(InstructionOperand * op)126   Constant ToConstant(InstructionOperand* op) {
127     if (op->IsImmediate()) {
128       return gen_->code()->GetImmediate(ImmediateOperand::cast(op));
129     }
130     return gen_->code()->GetConstant(
131         ConstantOperand::cast(op)->virtual_register());
132   }
133 
ToDouble(InstructionOperand * op)134   double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
135 
ToFloat32(InstructionOperand * op)136   float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }
137 
ToExternalReference(InstructionOperand * op)138   ExternalReference ToExternalReference(InstructionOperand* op) {
139     return ToConstant(op).ToExternalReference();
140   }
141 
ToHeapObject(InstructionOperand * op)142   Handle<HeapObject> ToHeapObject(InstructionOperand* op) {
143     return ToConstant(op).ToHeapObject();
144   }
145 
frame()146   const Frame* frame() const { return gen_->frame(); }
frame_access_state()147   FrameAccessState* frame_access_state() const {
148     return gen_->frame_access_state();
149   }
isolate()150   Isolate* isolate() const { return gen_->isolate(); }
linkage()151   Linkage* linkage() const { return gen_->linkage(); }
152 
153  protected:
154   CodeGenerator* gen_;
155   Instruction* instr_;
156 };
157 
158 // Eager deoptimization exit.
159 class DeoptimizationExit : public ZoneObject {
160  public:
DeoptimizationExit(int deoptimization_id)161   explicit DeoptimizationExit(int deoptimization_id)
162       : deoptimization_id_(deoptimization_id) {}
163 
deoptimization_id()164   int deoptimization_id() const { return deoptimization_id_; }
label()165   Label* label() { return &label_; }
166 
167  private:
168   int const deoptimization_id_;
169   Label label_;
170 };
171 
172 // Generator for out-of-line code that is emitted after the main code is done.
173 class OutOfLineCode : public ZoneObject {
174  public:
175   explicit OutOfLineCode(CodeGenerator* gen);
176   virtual ~OutOfLineCode();
177 
178   virtual void Generate() = 0;
179 
entry()180   Label* entry() { return &entry_; }
exit()181   Label* exit() { return &exit_; }
frame()182   const Frame* frame() const { return frame_; }
isolate()183   Isolate* isolate() const { return masm()->isolate(); }
masm()184   MacroAssembler* masm() const { return masm_; }
next()185   OutOfLineCode* next() const { return next_; }
186 
187  private:
188   Label entry_;
189   Label exit_;
190   const Frame* const frame_;
191   MacroAssembler* const masm_;
192   OutOfLineCode* const next_;
193 };
194 
195 
196 // TODO(dcarney): generify this on bleeding_edge and replace this call
197 // when merged.
FinishCode(MacroAssembler * masm)198 static inline void FinishCode(MacroAssembler* masm) {
199 #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
200   masm->CheckConstPool(true, false);
201 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
202   masm->ud2();
203 #endif
204 }
205 
206 }  // namespace compiler
207 }  // namespace internal
208 }  // namespace v8
209 
210 #endif  // V8_COMPILER_CODE_GENERATOR_IMPL_H
211