Home | History | Annotate | Download | only in compiler
      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:
     25   InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
     26       : gen_(gen), instr_(instr) {}
     27 
     28   // -- Instruction operand accesses with conversions --------------------------
     29 
     30   Register InputRegister(size_t index) {
     31     return ToRegister(instr_->InputAt(index));
     32   }
     33 
     34   DoubleRegister InputDoubleRegister(size_t index) {
     35     return ToDoubleRegister(instr_->InputAt(index));
     36   }
     37 
     38   double InputDouble(size_t index) { return ToDouble(instr_->InputAt(index)); }
     39 
     40   float InputFloat32(size_t index) { return ToFloat32(instr_->InputAt(index)); }
     41 
     42   int32_t InputInt32(size_t index) {
     43     return ToConstant(instr_->InputAt(index)).ToInt32();
     44   }
     45 
     46   int64_t InputInt64(size_t index) {
     47     return ToConstant(instr_->InputAt(index)).ToInt64();
     48   }
     49 
     50   int8_t InputInt8(size_t index) {
     51     return static_cast<int8_t>(InputInt32(index));
     52   }
     53 
     54   int16_t InputInt16(size_t index) {
     55     return static_cast<int16_t>(InputInt32(index));
     56   }
     57 
     58   uint8_t InputInt5(size_t index) {
     59     return static_cast<uint8_t>(InputInt32(index) & 0x1F);
     60   }
     61 
     62   uint8_t InputInt6(size_t index) {
     63     return static_cast<uint8_t>(InputInt32(index) & 0x3F);
     64   }
     65 
     66   ExternalReference InputExternalReference(size_t index) {
     67     return ToExternalReference(instr_->InputAt(index));
     68   }
     69 
     70   Handle<HeapObject> InputHeapObject(size_t index) {
     71     return ToHeapObject(instr_->InputAt(index));
     72   }
     73 
     74   Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
     75 
     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 
     84   Register TempRegister(size_t index) {
     85     return ToRegister(instr_->TempAt(index));
     86   }
     87 
     88   DoubleRegister OutputDoubleRegister() {
     89     return ToDoubleRegister(instr_->Output());
     90   }
     91 
     92   // -- Conversions for operands -----------------------------------------------
     93 
     94   Label* ToLabel(InstructionOperand* op) {
     95     return gen_->GetLabel(ToRpoNumber(op));
     96   }
     97 
     98   RpoNumber ToRpoNumber(InstructionOperand* op) {
     99     return ToConstant(op).ToRpoNumber();
    100   }
    101 
    102   Register ToRegister(InstructionOperand* op) {
    103     return LocationOperand::cast(op)->GetRegister();
    104   }
    105 
    106   DoubleRegister ToDoubleRegister(InstructionOperand* op) {
    107     return LocationOperand::cast(op)->GetDoubleRegister();
    108   }
    109 
    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 
    118   double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
    119 
    120   float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }
    121 
    122   ExternalReference ToExternalReference(InstructionOperand* op) {
    123     return ToConstant(op).ToExternalReference();
    124   }
    125 
    126   Handle<HeapObject> ToHeapObject(InstructionOperand* op) {
    127     return ToConstant(op).ToHeapObject();
    128   }
    129 
    130   Frame* frame() const { return gen_->frame(); }
    131   FrameAccessState* frame_access_state() const {
    132     return gen_->frame_access_state();
    133   }
    134   Isolate* isolate() const { return gen_->isolate(); }
    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 
    151   Label* entry() { return &entry_; }
    152   Label* exit() { return &exit_; }
    153   Frame* frame() const { return frame_; }
    154   Isolate* isolate() const { return masm()->isolate(); }
    155   MacroAssembler* masm() const { return masm_; }
    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.
    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