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