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/compiler/code-generator.h" 9 #include "src/compiler/common-operator.h" 10 #include "src/compiler/generic-graph.h" 11 #include "src/compiler/instruction.h" 12 #include "src/compiler/linkage.h" 13 #include "src/compiler/machine-operator.h" 14 #include "src/compiler/node.h" 15 #include "src/compiler/opcodes.h" 16 #include "src/compiler/operator.h" 17 18 namespace v8 { 19 namespace internal { 20 namespace compiler { 21 22 // Converts InstructionOperands from a given instruction to 23 // architecture-specific 24 // registers and operands after they have been assigned by the register 25 // allocator. 26 class InstructionOperandConverter { 27 public: InstructionOperandConverter(CodeGenerator * gen,Instruction * instr)28 InstructionOperandConverter(CodeGenerator* gen, Instruction* instr) 29 : gen_(gen), instr_(instr) {} 30 InputRegister(int index)31 Register InputRegister(int index) { 32 return ToRegister(instr_->InputAt(index)); 33 } 34 InputDoubleRegister(int index)35 DoubleRegister InputDoubleRegister(int index) { 36 return ToDoubleRegister(instr_->InputAt(index)); 37 } 38 InputDouble(int index)39 double InputDouble(int index) { return ToDouble(instr_->InputAt(index)); } 40 InputInt32(int index)41 int32_t InputInt32(int index) { 42 return ToConstant(instr_->InputAt(index)).ToInt32(); 43 } 44 InputInt8(int index)45 int8_t InputInt8(int index) { return static_cast<int8_t>(InputInt32(index)); } 46 InputInt16(int index)47 int16_t InputInt16(int index) { 48 return static_cast<int16_t>(InputInt32(index)); 49 } 50 InputInt5(int index)51 uint8_t InputInt5(int index) { 52 return static_cast<uint8_t>(InputInt32(index) & 0x1F); 53 } 54 InputInt6(int index)55 uint8_t InputInt6(int index) { 56 return static_cast<uint8_t>(InputInt32(index) & 0x3F); 57 } 58 InputHeapObject(int index)59 Handle<HeapObject> InputHeapObject(int index) { 60 return ToHeapObject(instr_->InputAt(index)); 61 } 62 InputLabel(int index)63 Label* InputLabel(int index) { 64 return gen_->code()->GetLabel(InputBlock(index)); 65 } 66 InputBlock(int index)67 BasicBlock* InputBlock(int index) { 68 NodeId block_id = static_cast<NodeId>(InputInt32(index)); 69 // operand should be a block id. 70 DCHECK(block_id >= 0); 71 DCHECK(block_id < gen_->schedule()->BasicBlockCount()); 72 return gen_->schedule()->GetBlockById(block_id); 73 } 74 75 Register OutputRegister(int index = 0) { 76 return ToRegister(instr_->OutputAt(index)); 77 } 78 OutputDoubleRegister()79 DoubleRegister OutputDoubleRegister() { 80 return ToDoubleRegister(instr_->Output()); 81 } 82 TempRegister(int index)83 Register TempRegister(int index) { return ToRegister(instr_->TempAt(index)); } 84 ToRegister(InstructionOperand * op)85 Register ToRegister(InstructionOperand* op) { 86 DCHECK(op->IsRegister()); 87 return Register::FromAllocationIndex(op->index()); 88 } 89 ToDoubleRegister(InstructionOperand * op)90 DoubleRegister ToDoubleRegister(InstructionOperand* op) { 91 DCHECK(op->IsDoubleRegister()); 92 return DoubleRegister::FromAllocationIndex(op->index()); 93 } 94 ToConstant(InstructionOperand * operand)95 Constant ToConstant(InstructionOperand* operand) { 96 if (operand->IsImmediate()) { 97 return gen_->code()->GetImmediate(operand->index()); 98 } 99 return gen_->code()->GetConstant(operand->index()); 100 } 101 ToDouble(InstructionOperand * operand)102 double ToDouble(InstructionOperand* operand) { 103 return ToConstant(operand).ToFloat64(); 104 } 105 ToHeapObject(InstructionOperand * operand)106 Handle<HeapObject> ToHeapObject(InstructionOperand* operand) { 107 return ToConstant(operand).ToHeapObject(); 108 } 109 frame()110 Frame* frame() const { return gen_->frame(); } isolate()111 Isolate* isolate() const { return gen_->isolate(); } linkage()112 Linkage* linkage() const { return gen_->linkage(); } 113 114 protected: 115 CodeGenerator* gen_; 116 Instruction* instr_; 117 }; 118 119 120 // TODO(dcarney): generify this on bleeding_edge and replace this call 121 // when merged. FinishCode(MacroAssembler * masm)122static inline void FinishCode(MacroAssembler* masm) { 123 #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM 124 masm->CheckConstPool(true, false); 125 #endif 126 } 127 128 } // namespace compiler 129 } // namespace internal 130 } // namespace v8 131 132 #endif // V8_COMPILER_CODE_GENERATOR_IMPL_H 133