Revision: 14782
Author: [email protected]
Date: Thu May 23 18:02:27 2013
Log: MIPS: Implement HChange support for Smis and use it in
Load/StoreNameField
Port r14765 (22625125)
BUG=
Review URL: https://codereview.chromium.org/15781006
http://code.google.com/p/v8/source/detail?r=14782
Modified:
/branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
/branches/bleeding_edge/src/mips/lithium-codegen-mips.h
/branches/bleeding_edge/src/mips/lithium-mips.cc
/branches/bleeding_edge/src/mips/lithium-mips.h
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed May 22
16:09:22 2013
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Thu May 23
18:02:27 2013
@@ -500,7 +500,7 @@
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::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 @@
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 @@
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));
@@ -4405,6 +4404,21 @@
}
__ cvt_d_w(ToDoubleRegister(output), single_scratch);
}
+
+
+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) {
@@ -4866,8 +4880,60 @@
// 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) {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Tue May 14
17:02:40 2013
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Thu May 23
18:02:27 2013
@@ -125,6 +125,7 @@
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
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Wed May 22 16:09:22
2013
+++ /branches/bleeding_edge/src/mips/lithium-mips.cc Thu May 23 18:02:27
2013
@@ -1760,12 +1760,24 @@
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 @@
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 @@
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 @@
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();
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.h Wed May 22 16:09:22 2013
+++ /branches/bleeding_edge/src/mips/lithium-mips.h Thu May 23 18:02:27 2013
@@ -95,6 +95,7 @@
V(Deoptimize) \
V(DivI) \
V(DoubleToI) \
+ V(DoubleToSmi) \
V(DummyUse) \
V(ElementsKind) \
V(FixedArrayBaseLength) \
@@ -111,6 +112,7 @@
V(InstanceSize) \
V(InstructionGap) \
V(Integer32ToDouble) \
+ V(Integer32ToSmi) \
V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
@@ -1901,6 +1903,19 @@
};
+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 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 LCheckSmi: public LTemplateInstruction<0, 1, 0> {
+class LCheckSmi: public LTemplateInstruction<1, 1, 0> {
public:
explicit LCheckSmi(LOperand* value) {
inputs_[0] = value;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.