15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2013 the V8 project authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef V8_COMPILER_CODE_GENERATOR_IMPL_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define V8_COMPILER_CODE_GENERATOR_IMPL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "src/compiler/code-generator.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "src/compiler/common-operator.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "src/compiler/generic-graph.h"
11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "src/compiler/instruction.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "src/compiler/linkage.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "src/compiler/machine-operator.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "src/compiler/node.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "src/compiler/opcodes.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "src/compiler/operator.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace v8 {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace compiler {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Converts InstructionOperands from a given instruction to
23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// architecture-specific
24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// registers and operands after they have been assigned by the register
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// allocator.
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class InstructionOperandConverter {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : gen_(gen), instr_(instr) {}
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Register InputRegister(int index) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ToRegister(instr_->InputAt(index));
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoubleRegister InputDoubleRegister(int index) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ToDoubleRegister(instr_->InputAt(index));
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double InputDouble(int index) { return ToDouble(instr_->InputAt(index)); }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t InputInt32(int index) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ToConstant(instr_->InputAt(index)).ToInt32();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int8_t InputInt8(int index) { return static_cast<int8_t>(InputInt32(index)); }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int16_t InputInt16(int index) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<int16_t>(InputInt32(index));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t InputInt5(int index) {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return static_cast<uint8_t>(InputInt32(index) & 0x1F);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t InputInt6(int index) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return static_cast<uint8_t>(InputInt32(index) & 0x3F);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Handle<HeapObject> InputHeapObject(int index) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ToHeapObject(instr_->InputAt(index));
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Label* InputLabel(int index) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gen_->code()->GetLabel(InputBlock(index));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BasicBlock* InputBlock(int index) {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NodeId block_id = static_cast<NodeId>(InputInt32(index));
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // operand should be a block id.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(block_id >= 0);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(block_id < gen_->schedule()->BasicBlockCount());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gen_->schedule()->GetBlockById(block_id);
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Register OutputRegister(int index = 0) {
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ToRegister(instr_->OutputAt(index));
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DoubleRegister OutputDoubleRegister() {
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ToDoubleRegister(instr_->Output());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Register TempRegister(int index) { return ToRegister(instr_->TempAt(index)); }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Register ToRegister(InstructionOperand* op) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(op->IsRegister());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Register::FromAllocationIndex(op->index());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoubleRegister ToDoubleRegister(InstructionOperand* op) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(op->IsDoubleRegister());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DoubleRegister::FromAllocationIndex(op->index());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Constant ToConstant(InstructionOperand* operand) {
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (operand->IsImmediate()) {
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gen_->code()->GetImmediate(operand->index());
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gen_->code()->GetConstant(operand->index());
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  double ToDouble(InstructionOperand* operand) {
103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return ToConstant(operand).ToFloat64();
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Handle<HeapObject> ToHeapObject(InstructionOperand* operand) {
107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return ToConstant(operand).ToHeapObject();
108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Frame* frame() const { return gen_->frame(); }
111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Isolate* isolate() const { return gen_->isolate(); }
112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Linkage* linkage() const { return gen_->linkage(); }
113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) protected:
115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CodeGenerator* gen_;
116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Instruction* instr_;
117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)};
118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// TODO(dcarney): generify this on bleeding_edge and replace this call
121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// when merged.
122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)static inline void FinishCode(MacroAssembler* masm) {
123b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  masm->CheckConstPool(true, false);
125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif
126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace compiler
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace internal
130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace v8
131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif  // V8_COMPILER_CODE_GENERATOR_IMPL_H
133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)