code-generator-impl.h 6.14 KB
Newer Older
1 2 3 4
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef V8_COMPILER_BACKEND_CODE_GENERATOR_IMPL_H_
#define V8_COMPILER_BACKEND_CODE_GENERATOR_IMPL_H_
7

8 9
#include "src/compiler/backend/code-generator.h"
#include "src/compiler/backend/instruction.h"
10 11
#include "src/compiler/linkage.h"
#include "src/compiler/opcodes.h"
12
#include "src/macro-assembler.h"
13 14 15 16 17 18 19 20 21 22 23 24 25 26

namespace v8 {
namespace internal {
namespace compiler {

// Converts InstructionOperands from a given instruction to
// architecture-specific
// registers and operands after they have been assigned by the register
// allocator.
class InstructionOperandConverter {
 public:
  InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
      : gen_(gen), instr_(instr) {}

27 28
  // -- Instruction operand accesses with conversions --------------------------

29
  Register InputRegister(size_t index) {
30 31 32
    return ToRegister(instr_->InputAt(index));
  }

33 34 35 36
  FloatRegister InputFloatRegister(size_t index) {
    return ToFloatRegister(instr_->InputAt(index));
  }

37
  DoubleRegister InputDoubleRegister(size_t index) {
38 39 40
    return ToDoubleRegister(instr_->InputAt(index));
  }

41 42 43 44
  Simd128Register InputSimd128Register(size_t index) {
    return ToSimd128Register(instr_->InputAt(index));
  }

45
  double InputDouble(size_t index) { return ToDouble(instr_->InputAt(index)); }
46

47 48
  float InputFloat32(size_t index) { return ToFloat32(instr_->InputAt(index)); }

49
  int32_t InputInt32(size_t index) {
50 51 52
    return ToConstant(instr_->InputAt(index)).ToInt32();
  }

53 54 55 56
  uint32_t InputUint32(size_t index) {
    return bit_cast<uint32_t>(InputInt32(index));
  }

57 58 59 60
  int64_t InputInt64(size_t index) {
    return ToConstant(instr_->InputAt(index)).ToInt64();
  }

61 62 63
  int8_t InputInt8(size_t index) {
    return static_cast<int8_t>(InputInt32(index));
  }
64

65
  int16_t InputInt16(size_t index) {
66 67 68
    return static_cast<int16_t>(InputInt32(index));
  }

69 70 71 72 73 74 75 76
  uint8_t InputInt3(size_t index) {
    return static_cast<uint8_t>(InputInt32(index) & 0x7);
  }

  uint8_t InputInt4(size_t index) {
    return static_cast<uint8_t>(InputInt32(index) & 0xF);
  }

77
  uint8_t InputInt5(size_t index) {
78 79 80
    return static_cast<uint8_t>(InputInt32(index) & 0x1F);
  }

81
  uint8_t InputInt6(size_t index) {
82 83 84
    return static_cast<uint8_t>(InputInt32(index) & 0x3F);
  }

85 86 87 88
  ExternalReference InputExternalReference(size_t index) {
    return ToExternalReference(instr_->InputAt(index));
  }

89 90
  Handle<Code> InputCode(size_t index) {
    return ToCode(instr_->InputAt(index));
91 92
  }

93
  Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
94

95
  RpoNumber InputRpo(size_t index) {
96
    return ToRpoNumber(instr_->InputAt(index));
97 98
  }

99
  Register OutputRegister(size_t index = 0) {
100 101
    return ToRegister(instr_->OutputAt(index));
  }
102

103 104 105
  Register TempRegister(size_t index) {
    return ToRegister(instr_->TempAt(index));
  }
106

107 108 109 110
  FloatRegister OutputFloatRegister() {
    return ToFloatRegister(instr_->Output());
  }

111 112 113 114
  DoubleRegister OutputDoubleRegister() {
    return ToDoubleRegister(instr_->Output());
  }

115 116 117 118
  Simd128Register OutputSimd128Register() {
    return ToSimd128Register(instr_->Output());
  }

119 120 121 122 123 124
  // -- Conversions for operands -----------------------------------------------

  Label* ToLabel(InstructionOperand* op) {
    return gen_->GetLabel(ToRpoNumber(op));
  }

125
  RpoNumber ToRpoNumber(InstructionOperand* op) {
126 127
    return ToConstant(op).ToRpoNumber();
  }
128 129

  Register ToRegister(InstructionOperand* op) {
130
    return LocationOperand::cast(op)->GetRegister();
131 132
  }

133 134 135 136
  FloatRegister ToFloatRegister(InstructionOperand* op) {
    return LocationOperand::cast(op)->GetFloatRegister();
  }

137
  DoubleRegister ToDoubleRegister(InstructionOperand* op) {
138
    return LocationOperand::cast(op)->GetDoubleRegister();
139 140
  }

141 142
  Simd128Register ToSimd128Register(InstructionOperand* op) {
    return LocationOperand::cast(op)->GetSimd128Register();
143 144
  }

145 146
  Constant ToConstant(InstructionOperand* op) {
    if (op->IsImmediate()) {
147
      return gen_->code()->GetImmediate(ImmediateOperand::cast(op));
148
    }
149 150
    return gen_->code()->GetConstant(
        ConstantOperand::cast(op)->virtual_register());
151 152
  }

153 154 155
  double ToDouble(InstructionOperand* op) {
    return ToConstant(op).ToFloat64().value();
  }
156

157 158
  float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }

159 160 161 162
  ExternalReference ToExternalReference(InstructionOperand* op) {
    return ToConstant(op).ToExternalReference();
  }

163 164
  Handle<Code> ToCode(InstructionOperand* op) {
    return ToConstant(op).ToCode();
165 166
  }

167
  const Frame* frame() const { return gen_->frame(); }
168 169 170
  FrameAccessState* frame_access_state() const {
    return gen_->frame_access_state();
  }
171 172 173 174 175 176 177 178
  Isolate* isolate() const { return gen_->isolate(); }
  Linkage* linkage() const { return gen_->linkage(); }

 protected:
  CodeGenerator* gen_;
  Instruction* instr_;
};

179 180 181
// Eager deoptimization exit.
class DeoptimizationExit : public ZoneObject {
 public:
182 183
  explicit DeoptimizationExit(int deoptimization_id, SourcePosition pos)
      : deoptimization_id_(deoptimization_id), pos_(pos) {}
184 185 186

  int deoptimization_id() const { return deoptimization_id_; }
  Label* label() { return &label_; }
187
  SourcePosition pos() const { return pos_; }
188 189 190 191

 private:
  int const deoptimization_id_;
  Label label_;
192
  SourcePosition const pos_;
193
};
194

195 196 197 198 199 200 201 202 203 204
// Generator for out-of-line code that is emitted after the main code is done.
class OutOfLineCode : public ZoneObject {
 public:
  explicit OutOfLineCode(CodeGenerator* gen);
  virtual ~OutOfLineCode();

  virtual void Generate() = 0;

  Label* entry() { return &entry_; }
  Label* exit() { return &exit_; }
205
  const Frame* frame() const { return frame_; }
206
  TurboAssembler* tasm() { return tasm_; }
207 208 209 210 211
  OutOfLineCode* next() const { return next_; }

 private:
  Label entry_;
  Label exit_;
212
  const Frame* const frame_;
213
  TurboAssembler* const tasm_;
214 215 216
  OutOfLineCode* const next_;
};

217 218 219 220 221
inline bool HasCallDescriptorFlag(Instruction* instr,
                                  CallDescriptor::Flag flag) {
  return MiscField::decode(instr->opcode()) & flag;
}

222 223 224 225
}  // namespace compiler
}  // namespace internal
}  // namespace v8

226
#endif  // V8_COMPILER_BACKEND_CODE_GENERATOR_IMPL_H_