| Index: src/ia32/lithium-ia32.cc
|
| diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
|
| index aa91a83406f3479590ab22e87747e8fd7f917b0e..27fa285cfea212d6d8910bf5ae75b78cca14cc5f 100644
|
| --- a/src/ia32/lithium-ia32.cc
|
| +++ b/src/ia32/lithium-ia32.cc
|
| @@ -804,9 +804,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
|
|
|
| LInstruction* LChunkBuilder::DoBit(Token::Value op,
|
| HBitwiseBinaryOperation* instr) {
|
| - if (instr->representation().IsInteger32()) {
|
| - ASSERT(instr->left()->representation().IsInteger32());
|
| - ASSERT(instr->right()->representation().IsInteger32());
|
| + if (instr->representation().IsInteger()) {
|
| + ASSERT(instr->left()->representation().IsInteger());
|
| + ASSERT(instr->right()->representation().IsInteger());
|
|
|
| LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
|
| LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
|
| @@ -836,9 +836,9 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
|
| return MarkAsCall(DefineFixed(result, eax), instr);
|
| }
|
|
|
| - ASSERT(instr->representation().IsInteger32());
|
| - ASSERT(instr->OperandAt(0)->representation().IsInteger32());
|
| - ASSERT(instr->OperandAt(1)->representation().IsInteger32());
|
| + ASSERT(instr->representation().IsInteger());
|
| + ASSERT(instr->OperandAt(0)->representation().IsInteger32X());
|
| + ASSERT(instr->OperandAt(1)->representation().IsInteger32X());
|
| LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
|
|
|
| HValue* right_value = instr->OperandAt(1);
|
| @@ -854,17 +854,9 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
|
|
|
| // Shift operations can only deoptimize if we do a logical shift
|
| // by 0 and the result cannot be truncated to int32.
|
| - bool can_deopt = (op == Token::SHR && constant_value == 0);
|
| - if (can_deopt) {
|
| - bool can_truncate = true;
|
| - for (int i = 0; i < instr->uses()->length(); i++) {
|
| - if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) {
|
| - can_truncate = false;
|
| - break;
|
| - }
|
| - }
|
| - can_deopt = !can_truncate;
|
| - }
|
| + bool can_deopt = op == Token::SHR &&
|
| + constant_value == 0 &&
|
| + !instr->representation().Equals(Representation::TruncatedInteger32());
|
|
|
| LShiftI* result = new LShiftI(op, left, right, can_deopt);
|
| return can_deopt
|
| @@ -1053,9 +1045,9 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) {
|
| HValue* left = compare->left();
|
| HValue* right = compare->right();
|
| Representation r = compare->GetInputRepresentation();
|
| - if (r.IsInteger32()) {
|
| - ASSERT(left->representation().IsInteger32());
|
| - ASSERT(right->representation().IsInteger32());
|
| + if (r.IsInteger()) {
|
| + ASSERT(left->representation().IsInteger());
|
| + ASSERT(right->representation().IsInteger());
|
|
|
| return new LCmpIDAndBranch(UseRegisterAtStart(left),
|
| UseOrConstantAtStart(right));
|
| @@ -1349,8 +1341,8 @@ LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
|
| - ASSERT(instr->value()->representation().IsInteger32());
|
| - ASSERT(instr->representation().IsInteger32());
|
| + ASSERT(instr->value()->representation().IsInteger());
|
| + ASSERT(instr->representation().IsInteger32X());
|
| LOperand* input = UseRegisterAtStart(instr->value());
|
| LBitNotI* result = new LBitNotI(input);
|
| return DefineSameAsFirst(result);
|
| @@ -1370,7 +1362,8 @@ LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
|
| LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
|
| if (instr->representation().IsDouble()) {
|
| return DoArithmeticD(Token::DIV, instr);
|
| - } else if (instr->representation().IsInteger32()) {
|
| + } else if (instr->representation().IsInteger()) {
|
| + ASSERT(instr->representation().IsInteger32X());
|
| // The temporary operand is necessary to ensure that right is not allocated
|
| // into edx.
|
| LOperand* temp = FixedTemp(edx);
|
| @@ -1386,9 +1379,9 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
| - if (instr->representation().IsInteger32()) {
|
| - ASSERT(instr->left()->representation().IsInteger32());
|
| - ASSERT(instr->right()->representation().IsInteger32());
|
| + if (instr->representation().IsInteger32X()) {
|
| + ASSERT(instr->left()->representation().IsInteger());
|
| + ASSERT(instr->right()->representation().IsInteger());
|
|
|
| LInstruction* result;
|
| if (instr->HasPowerOf2Divisor()) {
|
| @@ -1426,9 +1419,9 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoMul(HMul* instr) {
|
| - if (instr->representation().IsInteger32()) {
|
| - ASSERT(instr->left()->representation().IsInteger32());
|
| - ASSERT(instr->right()->representation().IsInteger32());
|
| + if (instr->representation().IsInteger32X()) {
|
| + ASSERT(instr->left()->representation().IsInteger());
|
| + ASSERT(instr->right()->representation().IsInteger());
|
| LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
|
| LOperand* right = UseOrConstant(instr->MostConstantOperand());
|
| LOperand* temp = NULL;
|
| @@ -1447,9 +1440,9 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoSub(HSub* instr) {
|
| - if (instr->representation().IsInteger32()) {
|
| - ASSERT(instr->left()->representation().IsInteger32());
|
| - ASSERT(instr->right()->representation().IsInteger32());
|
| + if (instr->representation().IsInteger32X()) {
|
| + ASSERT(instr->left()->representation().IsInteger());
|
| + ASSERT(instr->right()->representation().IsInteger());
|
| LOperand* left = UseRegisterAtStart(instr->left());
|
| LOperand* right = UseOrConstantAtStart(instr->right());
|
| LSubI* sub = new LSubI(left, right);
|
| @@ -1468,9 +1461,9 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
|
| - if (instr->representation().IsInteger32()) {
|
| - ASSERT(instr->left()->representation().IsInteger32());
|
| - ASSERT(instr->right()->representation().IsInteger32());
|
| + if (instr->representation().IsInteger32X()) {
|
| + ASSERT(instr->left()->representation().IsInteger());
|
| + ASSERT(instr->right()->representation().IsInteger());
|
| LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
|
| LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
|
| LAddI* add = new LAddI(left, right);
|
| @@ -1507,9 +1500,9 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
|
| LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
|
| Token::Value op = instr->token();
|
| Representation r = instr->GetInputRepresentation();
|
| - if (r.IsInteger32()) {
|
| - ASSERT(instr->left()->representation().IsInteger32());
|
| - ASSERT(instr->right()->representation().IsInteger32());
|
| + if (r.IsInteger32X()) {
|
| + ASSERT(instr->left()->representation().IsInteger());
|
| + ASSERT(instr->right()->representation().IsInteger());
|
| LOperand* left = UseRegisterAtStart(instr->left());
|
| LOperand* right = UseOrConstantAtStart(instr->right());
|
| return DefineAsRegister(new LCmpID(left, right));
|
| @@ -1652,18 +1645,21 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
| LNumberUntagD* res = new LNumberUntagD(value);
|
| return AssignEnvironment(DefineAsRegister(res));
|
| } else {
|
| - ASSERT(to.IsInteger32());
|
| + ASSERT(to.IsInteger());
|
| LOperand* value = UseRegister(instr->value());
|
| bool needs_check = !instr->value()->type().IsSmi();
|
| + bool needs_temp = to.IsClampedRoundedInteger8() ||
|
| + (!(CpuFeatures::IsSupported(SSE3) && to.IsTruncatedInteger32()));
|
| + ToIRoundingMode rounding_mode(RepresentationToRoundingMode(to));
|
| if (needs_check) {
|
| - LOperand* xmm_temp =
|
| - (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3))
|
| - ? NULL
|
| - : FixedTemp(xmm1);
|
| - LTaggedToI* res = new LTaggedToI(value, xmm_temp);
|
| + LOperand* xmm_temp = needs_temp ? FixedTemp(xmm1) : NULL;
|
| + LTaggedToI* res = new LTaggedToI(value, xmm_temp, rounding_mode);
|
| return AssignEnvironment(DefineSameAsFirst(res));
|
| } else {
|
| - return DefineSameAsFirst(new LSmiUntag(value, needs_check));
|
| + bool should_clamp = to.IsClampedRoundedInteger8();
|
| + return DefineSameAsFirst(new LSmiUntag(value,
|
| + false,
|
| + should_clamp));
|
| }
|
| }
|
| } else if (from.IsDouble()) {
|
| @@ -1676,15 +1672,18 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
| LNumberTagD* result = new LNumberTagD(value, temp);
|
| return AssignPointerMap(Define(result, result_temp));
|
| } else {
|
| - ASSERT(to.IsInteger32());
|
| - bool needs_temp = instr->CanTruncateToInt32() &&
|
| - !CpuFeatures::IsSupported(SSE3);
|
| + ASSERT(to.IsInteger());
|
| + ToIRoundingMode rounding_mode(RepresentationToRoundingMode(to));
|
| + bool needs_temp = to.IsClampedRoundedInteger8() ||
|
| + (!(CpuFeatures::IsSupported(SSE3) && to.IsTruncatedInteger32()));
|
| LOperand* value = needs_temp ?
|
| UseTempRegister(instr->value()) : UseRegister(instr->value());
|
| LOperand* temp = needs_temp ? TempRegister() : NULL;
|
| - return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp)));
|
| + return AssignEnvironment(DefineAsRegister(new LDoubleToI(value,
|
| + temp,
|
| + rounding_mode)));
|
| }
|
| - } else if (from.IsInteger32()) {
|
| + } else if (from.IsInteger()) {
|
| if (to.IsTagged()) {
|
| HValue* val = instr->value();
|
| LOperand* value = UseRegister(val);
|
| @@ -1694,6 +1693,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
| LNumberTagI* result = new LNumberTagI(value);
|
| return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
|
| }
|
| + } else if (to.IsClampedRoundedInteger8()) {
|
| + return DefineFixed(new LInteger32ToClamped(
|
| + UseFixed(instr->value(), eax)), eax);
|
| } else {
|
| ASSERT(to.IsDouble());
|
| return DefineAsRegister(new LInteger32ToDouble(Use(instr->value())));
|
| @@ -1751,7 +1753,7 @@ LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
|
|
|
| LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
|
| Representation r = instr->representation();
|
| - if (r.IsInteger32()) {
|
| + if (r.IsInteger()) {
|
| return DefineAsRegister(new LConstantI);
|
| } else if (r.IsDouble()) {
|
| double value = instr->DoubleValue();
|
| @@ -1878,7 +1880,7 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
|
| LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
|
| HLoadKeyedFastElement* instr) {
|
| ASSERT(instr->representation().IsTagged());
|
| - ASSERT(instr->key()->representation().IsInteger32());
|
| + ASSERT(instr->key()->representation().IsInteger32X());
|
| LOperand* obj = UseRegisterAtStart(instr->object());
|
| LOperand* key = UseRegisterAtStart(instr->key());
|
| LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
|
| @@ -1890,9 +1892,9 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
|
| HLoadKeyedSpecializedArrayElement* instr) {
|
| ExternalArrayType array_type = instr->array_type();
|
| Representation representation(instr->representation());
|
| - ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
|
| + ASSERT((representation.IsInteger32X() && array_type != kExternalFloatArray) ||
|
| (representation.IsDouble() && array_type == kExternalFloatArray));
|
| - ASSERT(instr->key()->representation().IsInteger32());
|
| + ASSERT(instr->key()->representation().IsInteger32X());
|
| LOperand* external_pointer = UseRegister(instr->external_pointer());
|
| LOperand* key = UseRegister(instr->key());
|
| LLoadKeyedSpecializedArrayElement* result =
|
| @@ -1922,7 +1924,7 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
|
| bool needs_write_barrier = instr->NeedsWriteBarrier();
|
| ASSERT(instr->value()->representation().IsTagged());
|
| ASSERT(instr->object()->representation().IsTagged());
|
| - ASSERT(instr->key()->representation().IsInteger32());
|
| + ASSERT(instr->key()->representation().IsInteger32X());
|
|
|
| LOperand* obj = UseTempRegister(instr->object());
|
| LOperand* val = needs_write_barrier
|
| @@ -1940,25 +1942,16 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
|
| HStoreKeyedSpecializedArrayElement* instr) {
|
| Representation representation(instr->value()->representation());
|
| ExternalArrayType array_type = instr->array_type();
|
| - ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
|
| - (representation.IsDouble() && array_type == kExternalFloatArray));
|
| ASSERT(instr->external_pointer()->representation().IsExternal());
|
| - ASSERT(instr->key()->representation().IsInteger32());
|
| + ASSERT(instr->key()->representation().IsInteger32X());
|
|
|
| LOperand* external_pointer = UseRegister(instr->external_pointer());
|
| LOperand* key = UseRegister(instr->key());
|
| - LOperand* temp = NULL;
|
| -
|
| - if (array_type == kExternalPixelArray) {
|
| - // The generated code for pixel array stores requires that the clamped value
|
| - // is in a byte register. eax is an arbitrary choice to satisfy this
|
| - // requirement.
|
| - temp = FixedTemp(eax);
|
| - }
|
|
|
| LOperand* val = NULL;
|
| if (array_type == kExternalByteArray ||
|
| - array_type == kExternalUnsignedByteArray) {
|
| + array_type == kExternalUnsignedByteArray ||
|
| + array_type == kExternalPixelArray) {
|
| // We need a byte register in this case for the value.
|
| val = UseFixed(instr->value(), eax);
|
| } else {
|
| @@ -1967,8 +1960,7 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
|
|
|
| return new LStoreKeyedSpecializedArrayElement(external_pointer,
|
| key,
|
| - val,
|
| - temp);
|
| + val);
|
| }
|
|
|
|
|
|
|