| Index: src/compiler/change-lowering.cc
|
| diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc
|
| index 5813be1d751f7f18a83a8d285e548e8fb77bb73d..ab5b66231e9490b8d8664e02d8bec1a062f4baf1 100644
|
| --- a/src/compiler/change-lowering.cc
|
| +++ b/src/compiler/change-lowering.cc
|
| @@ -28,6 +28,8 @@ Reduction ChangeLowering::Reduce(Node* node) {
|
| return ChangeTaggedToFloat64(node->InputAt(0), control);
|
| case IrOpcode::kChangeTaggedToInt32:
|
| return ChangeTaggedToInt32(node->InputAt(0), control);
|
| + case IrOpcode::kChangeUint32ToTagged:
|
| + return ChangeUint32ToTagged(node->InputAt(0), control);
|
| default:
|
| return NoChange();
|
| }
|
| @@ -44,6 +46,20 @@ Node* ChangeLowering::HeapNumberValueIndexConstant() {
|
| }
|
|
|
|
|
| +Node* ChangeLowering::SmiMaxValueConstant() {
|
| + // TODO(turbofan): Work-around for weird GCC 4.6 linker issue:
|
| + // src/compiler/change-lowering.cc:46: undefined reference to
|
| + // `v8::internal::SmiTagging<4u>::kSmiValueSize'
|
| + // src/compiler/change-lowering.cc:46: undefined reference to
|
| + // `v8::internal::SmiTagging<8u>::kSmiValueSize'
|
| + STATIC_ASSERT(SmiTagging<4>::kSmiValueSize == 31);
|
| + STATIC_ASSERT(SmiTagging<8>::kSmiValueSize == 32);
|
| + const int smi_value_size = machine()->is64() ? 32 : 31;
|
| + return jsgraph()->Int32Constant(
|
| + -(static_cast<int>(0xffffffffu << (smi_value_size - 1)) + 1));
|
| +}
|
| +
|
| +
|
| Node* ChangeLowering::SmiShiftBitsConstant() {
|
| // TODO(turbofan): Work-around for weird GCC 4.6 linker issue:
|
| // src/compiler/change-lowering.cc:46: undefined reference to
|
| @@ -170,6 +186,33 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) {
|
| }
|
|
|
|
|
| +Reduction ChangeLowering::ChangeUint32ToTagged(Node* val, Node* control) {
|
| + STATIC_ASSERT(kSmiTag == 0);
|
| + STATIC_ASSERT(kSmiTagMask == 1);
|
| +
|
| + Node* cmp = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val,
|
| + SmiMaxValueConstant());
|
| + Node* branch = graph()->NewNode(common()->Branch(), cmp, control);
|
| +
|
| + Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
| + Node* smi = graph()->NewNode(
|
| + machine()->WordShl(),
|
| + machine()->is64()
|
| + ? graph()->NewNode(machine()->ChangeUint32ToUint64(), val)
|
| + : val,
|
| + SmiShiftBitsConstant());
|
| +
|
| + Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
| + Node* heap_number = AllocateHeapNumberWithValue(
|
| + graph()->NewNode(machine()->ChangeUint32ToFloat64(), val), if_false);
|
| +
|
| + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
|
| + Node* phi = graph()->NewNode(common()->Phi(2), smi, heap_number, merge);
|
| +
|
| + return Replace(phi);
|
| +}
|
| +
|
| +
|
| Isolate* ChangeLowering::isolate() const { return jsgraph()->isolate(); }
|
|
|
|
|
|
|