case Constant::kInt64:
case Constant::kExternalReference:
case Constant::kHeapObject:
+ case Constant::kRpoNumber:
break;
}
UNREACHABLE();
case Constant::kHeapObject:
__ Move(dst, src.ToHeapObject());
break;
+ case Constant::kRpoNumber:
+ UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm.
+ break;
}
if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination));
} else if (src.type() == Constant::kFloat32) {
return Operand(constant.ToExternalReference());
case Constant::kHeapObject:
return Operand(constant.ToHeapObject());
+ case Constant::kRpoNumber:
+ UNREACHABLE(); // TODO(dcarney): RPO immediates on arm64.
+ break;
}
UNREACHABLE();
return Operand(-1);
InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
: gen_(gen), instr_(instr) {}
+ // -- Instruction operand accesses with conversions --------------------------
+
Register InputRegister(int index) {
return ToRegister(instr_->InputAt(index));
}
return ToHeapObject(instr_->InputAt(index));
}
- Label* InputLabel(int index) { return gen_->GetLabel(InputRpo(index)); }
+ Label* InputLabel(int index) { return ToLabel(instr_->InputAt(index)); }
BasicBlock::RpoNumber InputRpo(int index) {
- int rpo_number = InputInt32(index);
- return BasicBlock::RpoNumber::FromInt(rpo_number);
+ return ToRpoNumber(instr_->InputAt(index));
}
Register OutputRegister(int index = 0) {
return ToRegister(instr_->OutputAt(index));
}
+ Register TempRegister(int index) { return ToRegister(instr_->TempAt(index)); }
+
DoubleRegister OutputDoubleRegister() {
return ToDoubleRegister(instr_->Output());
}
- Register TempRegister(int index) { return ToRegister(instr_->TempAt(index)); }
+ // -- Conversions for operands -----------------------------------------------
+
+ Label* ToLabel(InstructionOperand* op) {
+ return gen_->GetLabel(ToRpoNumber(op));
+ }
+
+ BasicBlock::RpoNumber ToRpoNumber(InstructionOperand* op) {
+ return ToConstant(op).ToRpoNumber();
+ }
Register ToRegister(InstructionOperand* op) {
DCHECK(op->IsRegister());
return DoubleRegister::FromAllocationIndex(op->index());
}
- Constant ToConstant(InstructionOperand* operand) {
- if (operand->IsImmediate()) {
- return gen_->code()->GetImmediate(operand->index());
+ Constant ToConstant(InstructionOperand* op) {
+ if (op->IsImmediate()) {
+ return gen_->code()->GetImmediate(op->index());
}
- return gen_->code()->GetConstant(operand->index());
+ return gen_->code()->GetConstant(op->index());
}
- double ToDouble(InstructionOperand* operand) {
- return ToConstant(operand).ToFloat64();
- }
+ double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
- Handle<HeapObject> ToHeapObject(InstructionOperand* operand) {
- return ToConstant(operand).ToHeapObject();
+ Handle<HeapObject> ToHeapObject(InstructionOperand* op) {
+ return ToConstant(op).ToHeapObject();
}
Frame* frame() const { return gen_->frame(); }
return Immediate(constant.ToHeapObject());
case Constant::kInt64:
break;
+ case Constant::kRpoNumber:
+ return Immediate::CodeRelativeOffset(ToLabel(operand));
}
UNREACHABLE();
return Immediate(-1);
}
InstructionOperand* Label(BasicBlock* block) {
- // TODO(bmeurer): We misuse ImmediateOperand here.
- return TempImmediate(block->rpo_number());
+ int index = sequence()->AddImmediate(Constant(block->GetRpoNumber()));
+ return ImmediateOperand::Create(index, zone());
}
protected:
constant.ToExternalReference().address());
case Constant::kHeapObject:
return os << Brief(*constant.ToHeapObject());
+ case Constant::kRpoNumber:
+ return os << "RPO" << constant.ToRpoNumber().ToInt();
}
UNREACHABLE();
return os;
kFloat32,
kFloat64,
kExternalReference,
- kHeapObject
+ kHeapObject,
+ kRpoNumber
};
explicit Constant(int32_t v) : type_(kInt32), value_(v) {}
: type_(kExternalReference), value_(bit_cast<intptr_t>(ref)) {}
explicit Constant(Handle<HeapObject> obj)
: type_(kHeapObject), value_(bit_cast<intptr_t>(obj)) {}
+ explicit Constant(BasicBlock::RpoNumber rpo)
+ : type_(kRpoNumber), value_(rpo.ToInt()) {}
Type type() const { return type_; }
return bit_cast<ExternalReference>(static_cast<intptr_t>(value_));
}
+ BasicBlock::RpoNumber ToRpoNumber() const {
+ DCHECK_EQ(kRpoNumber, type());
+ return BasicBlock::RpoNumber::FromInt(static_cast<int>(value_));
+ }
+
Handle<HeapObject> ToHeapObject() const {
DCHECK_EQ(kHeapObject, type());
return bit_cast<Handle<HeapObject> >(static_cast<intptr_t>(value_));
PhiInstructions phis_;
const BasicBlock::Id id_;
const BasicBlock::RpoNumber ao_number_; // Assembly order number.
- // TODO(dcarney): probably dont't need this.
const BasicBlock::RpoNumber rpo_number_;
const BasicBlock::RpoNumber loop_header_;
const BasicBlock::RpoNumber loop_end_;
// TODO(plind): Maybe we should handle ExtRef & HeapObj here?
// maybe not done on arm due to const pool ??
break;
+ case Constant::kRpoNumber:
+ UNREACHABLE(); // TODO(titzer): RPO immediates on mips?
+ break;
}
UNREACHABLE();
return Operand(zero_reg);
case Constant::kHeapObject:
__ li(dst, src.ToHeapObject());
break;
+ case Constant::kRpoNumber:
+ UNREACHABLE(); // TODO(titzer): loading RPO numbers on mips.
+ break;
}
if (destination->IsStackSlot()) __ sw(dst, g.ToMemOperand(destination));
} else if (src.type() == Constant::kFloat32) {
// TODO(plind): Maybe we should handle ExtRef & HeapObj here?
// maybe not done on arm due to const pool ??
break;
+ case Constant::kRpoNumber:
+ UNREACHABLE(); // TODO(titzer): RPO immediates on mips?
+ break;
}
UNREACHABLE();
return Operand(zero_reg);
case Constant::kHeapObject:
__ li(dst, src.ToHeapObject());
break;
+ case Constant::kRpoNumber:
+ UNREACHABLE(); // TODO(titzer): loading RPO numbers on mips64.
+ break;
}
if (destination->IsStackSlot()) __ sd(dst, g.ToMemOperand(destination));
} else if (src.type() == Constant::kFloat32) {
case Constant::kHeapObject:
__ Move(dst, src.ToHeapObject());
break;
+ case Constant::kRpoNumber:
+ UNREACHABLE(); // TODO(dcarney): load of labels on x64.
+ break;
}
if (destination->IsStackSlot()) {
__ movq(g.ToOperand(destination), kScratchRegister);