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