• 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