MIPS: Implement HChange support for Smis and use it in Load/StoreNameField
Port r14765 (22625125) BUG= Review URL: https://codereview.chromium.org/15781006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14782 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b2e8d4c5b3
commit
ae74636c9e
@ -500,7 +500,7 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
|
||||
|
||||
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
|
||||
HConstant* constant = chunk_->LookupConstant(op);
|
||||
ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
|
||||
ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
|
||||
return constant->handle();
|
||||
}
|
||||
|
||||
@ -510,6 +510,11 @@ bool LCodeGen::IsInteger32(LConstantOperand* op) const {
|
||||
}
|
||||
|
||||
|
||||
bool LCodeGen::IsSmi(LConstantOperand* op) const {
|
||||
return chunk_->LookupLiteralRepresentation(op).IsSmi();
|
||||
}
|
||||
|
||||
|
||||
int LCodeGen::ToInteger32(LConstantOperand* op) const {
|
||||
HConstant* constant = chunk_->LookupConstant(op);
|
||||
return constant->Integer32Value();
|
||||
@ -1837,7 +1842,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
||||
int false_block = chunk_->LookupDestination(instr->false_block_id());
|
||||
|
||||
Representation r = instr->hydrogen()->value()->representation();
|
||||
if (r.IsInteger32()) {
|
||||
if (r.IsInteger32() || r.IsSmi()) {
|
||||
Register reg = ToRegister(instr->value());
|
||||
EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
|
||||
} else if (r.IsDouble()) {
|
||||
@ -3898,13 +3903,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
||||
|
||||
Handle<Map> transition = instr->transition();
|
||||
|
||||
if (FLAG_track_fields && representation.IsSmi()) {
|
||||
Register value = ToRegister(instr->value());
|
||||
__ SmiTagCheckOverflow(value, value, scratch);
|
||||
if (!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
||||
DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
|
||||
}
|
||||
} else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
|
||||
if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
|
||||
Register value = ToRegister(instr->value());
|
||||
if (!instr->hydrogen()->value()->type().IsHeapObject()) {
|
||||
__ And(scratch, value, Operand(kSmiTagMask));
|
||||
@ -4407,6 +4406,21 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
|
||||
LOperand* input = instr->value();
|
||||
ASSERT(input->IsRegister());
|
||||
LOperand* output = instr->result();
|
||||
ASSERT(output->IsRegister());
|
||||
Register scratch = scratch0();
|
||||
|
||||
__ SmiTagCheckOverflow(ToRegister(output), ToRegister(input), scratch);
|
||||
if (!instr->hydrogen()->value()->HasRange() ||
|
||||
!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
||||
DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
||||
LOperand* input = instr->value();
|
||||
LOperand* output = instr->result();
|
||||
@ -4866,10 +4880,62 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
|
||||
|
||||
// Deopt if the operation did not succeed (except_flag != 0).
|
||||
DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
|
||||
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
Label done;
|
||||
__ Branch(&done, ne, result_reg, Operand(zero_reg));
|
||||
__ mfc1(scratch1, double_input.high());
|
||||
__ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
|
||||
DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
|
||||
Register result_reg = ToRegister(instr->result());
|
||||
Register scratch1 = scratch0();
|
||||
Register scratch2 = ToRegister(instr->temp());
|
||||
DoubleRegister double_input = ToDoubleRegister(instr->value());
|
||||
|
||||
if (instr->truncating()) {
|
||||
Register scratch3 = ToRegister(instr->temp2());
|
||||
FPURegister single_scratch = double_scratch0().low();
|
||||
__ EmitECMATruncate(result_reg,
|
||||
double_input,
|
||||
single_scratch,
|
||||
scratch1,
|
||||
scratch2,
|
||||
scratch3);
|
||||
} else {
|
||||
Register except_flag = scratch2;
|
||||
|
||||
__ EmitFPUTruncate(kRoundToMinusInf,
|
||||
result_reg,
|
||||
double_input,
|
||||
scratch1,
|
||||
double_scratch0(),
|
||||
except_flag,
|
||||
kCheckForInexactConversion);
|
||||
|
||||
// Deopt if the operation did not succeed (except_flag != 0).
|
||||
DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
|
||||
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
Label done;
|
||||
__ Branch(&done, ne, result_reg, Operand(zero_reg));
|
||||
__ mfc1(scratch1, double_input.high());
|
||||
__ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
|
||||
DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
__ SmiTagCheckOverflow(result_reg, result_reg, scratch1);
|
||||
DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
|
||||
LOperand* input = instr->value();
|
||||
__ And(at, ToRegister(input), Operand(kSmiTagMask));
|
||||
|
@ -125,6 +125,7 @@ class LCodeGen BASE_EMBEDDED {
|
||||
MemOperand ToHighMemOperand(LOperand* op) const;
|
||||
|
||||
bool IsInteger32(LConstantOperand* op) const;
|
||||
bool IsSmi(LConstantOperand* op) const;
|
||||
Handle<Object> ToHandle(LConstantOperand* op) const;
|
||||
|
||||
// Try to generate code for the entire chunk, but it may fail if the
|
||||
|
@ -1760,12 +1760,24 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
|
||||
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
Representation from = instr->from();
|
||||
Representation to = instr->to();
|
||||
if (from.IsSmi()) {
|
||||
if (to.IsTagged()) {
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
return DefineSameAsFirst(new(zone()) LDummyUse(value));
|
||||
}
|
||||
from = Representation::Tagged();
|
||||
}
|
||||
if (from.IsTagged()) {
|
||||
if (to.IsDouble()) {
|
||||
info()->MarkAsDeferredCalling();
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
LNumberUntagD* res = new(zone()) LNumberUntagD(value);
|
||||
return AssignEnvironment(DefineAsRegister(res));
|
||||
} else if (to.IsSmi()) {
|
||||
HValue* val = instr->value();
|
||||
LOperand* value = UseRegisterAtStart(val);
|
||||
return AssignEnvironment(
|
||||
DefineSameAsFirst(new(zone()) LCheckSmi(value)));
|
||||
} else {
|
||||
ASSERT(to.IsInteger32());
|
||||
LOperand* value = NULL;
|
||||
@ -1807,6 +1819,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
|
||||
Define(result, result_temp);
|
||||
return AssignPointerMap(result);
|
||||
} else if (to.IsSmi()) {
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
return AssignEnvironment(DefineAsRegister(new(zone()) LDoubleToSmi(value,
|
||||
TempRegister(), TempRegister())));
|
||||
} else {
|
||||
ASSERT(to.IsInteger32());
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
@ -1829,6 +1845,15 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
LNumberTagI* result = new(zone()) LNumberTagI(value);
|
||||
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
|
||||
}
|
||||
} else if (to.IsSmi()) {
|
||||
HValue* val = instr->value();
|
||||
LOperand* value = UseRegister(val);
|
||||
LInstruction* result =
|
||||
DefineSameAsFirst(new(zone()) LInteger32ToSmi(value));
|
||||
if (val->HasRange() && val->range()->IsInSmiRange()) {
|
||||
return result;
|
||||
}
|
||||
return AssignEnvironment(result);
|
||||
} else {
|
||||
ASSERT(to.IsDouble());
|
||||
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
|
||||
@ -1923,7 +1948,7 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
|
||||
return DefineAsRegister(new(zone()) LConstantI);
|
||||
} else if (r.IsDouble()) {
|
||||
return DefineAsRegister(new(zone()) LConstantD);
|
||||
} else if (r.IsTagged()) {
|
||||
} else if (r.IsTagged() || r.IsSmi()) {
|
||||
return DefineAsRegister(new(zone()) LConstantT);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
|
@ -95,6 +95,7 @@ class LCodeGen;
|
||||
V(Deoptimize) \
|
||||
V(DivI) \
|
||||
V(DoubleToI) \
|
||||
V(DoubleToSmi) \
|
||||
V(DummyUse) \
|
||||
V(ElementsKind) \
|
||||
V(FixedArrayBaseLength) \
|
||||
@ -111,6 +112,7 @@ class LCodeGen;
|
||||
V(InstanceSize) \
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(Integer32ToSmi) \
|
||||
V(Uint32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
@ -1901,6 +1903,19 @@ class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LInteger32ToSmi: public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LInteger32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LUint32ToDouble: public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LUint32ToDouble(LOperand* value) {
|
||||
@ -1954,6 +1969,25 @@ class LNumberTagD: public LTemplateInstruction<1, 1, 2> {
|
||||
};
|
||||
|
||||
|
||||
class LDoubleToSmi: public LTemplateInstruction<1, 1, 2> {
|
||||
public:
|
||||
LDoubleToSmi(LOperand* value, LOperand* temp, LOperand* temp2) {
|
||||
inputs_[0] = value;
|
||||
temps_[0] = temp;
|
||||
temps_[1] = temp2;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
LOperand* temp2() { return temps_[1]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
|
||||
|
||||
bool truncating() { return hydrogen()->CanTruncateToInt32(); }
|
||||
};
|
||||
|
||||
|
||||
// Sometimes truncating conversion from a tagged value to an int32.
|
||||
class LDoubleToI: public LTemplateInstruction<1, 1, 2> {
|
||||
public:
|
||||
@ -2294,7 +2328,7 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 2> {
|
||||
};
|
||||
|
||||
|
||||
class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
|
||||
class LCheckSmi: public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LCheckSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
|
Loading…
Reference in New Issue
Block a user