| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index 46c71e8b1753bdf65d5d385c2bb24770024443eb..1a837431007faa4f0ff52b6d7e5c69293bbb6cec 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -283,7 +283,7 @@ XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
|
|
|
| int LCodeGen::ToInteger32(LConstantOperand* op) const {
|
| Handle<Object> value = chunk_->LookupLiteral(op);
|
| - ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
|
| + ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger());
|
| ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) ==
|
| value->Number());
|
| return static_cast<int32_t>(value->Number());
|
| @@ -294,9 +294,13 @@ Immediate LCodeGen::ToImmediate(LOperand* op) {
|
| LConstantOperand* const_op = LConstantOperand::cast(op);
|
| Handle<Object> literal = chunk_->LookupLiteral(const_op);
|
| Representation r = chunk_->LookupLiteralRepresentation(const_op);
|
| - if (r.IsInteger32()) {
|
| + if (r.IsInteger()) {
|
| ASSERT(literal->IsNumber());
|
| - return Immediate(static_cast<int32_t>(literal->Number()));
|
| + if (r.IsClampedRoundedInteger8()) {
|
| + return Immediate(ClampToUInt8(literal->Number()));
|
| + } else {
|
| + return Immediate(static_cast<int32_t>(literal->Number()));
|
| + }
|
| } else if (r.IsDouble()) {
|
| Abort("unsupported double immediate");
|
| }
|
| @@ -1283,7 +1287,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| int false_block = chunk_->LookupDestination(instr->false_block_id());
|
|
|
| Representation r = instr->hydrogen()->representation();
|
| - if (r.IsInteger32()) {
|
| + if (r.IsInteger()) {
|
| Register reg = ToRegister(instr->InputAt(0));
|
| __ test(reg, Operand(reg));
|
| EmitBranch(true_block, false_block, not_zero);
|
| @@ -2665,7 +2669,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
|
| __ pxor(scratch, scratch);
|
| __ subsd(scratch, input_reg);
|
| __ pand(input_reg, scratch);
|
| - } else if (r.IsInteger32()) {
|
| + } else if (r.IsInteger()) {
|
| EmitIntegerMathAbs(instr);
|
| } else { // Tagged case.
|
| DeferredMathAbsTaggedHeapNumber* deferred =
|
| @@ -2780,7 +2784,7 @@ void LCodeGen::DoPower(LPower* instr) {
|
| __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
|
| __ CallCFunction(ExternalReference::power_double_double_function(isolate()),
|
| 4);
|
| - } else if (exponent_type.IsInteger32()) {
|
| + } else if (exponent_type.IsInteger()) {
|
| // It is safe to use ebx directly since the instruction is marked
|
| // as a call.
|
| ASSERT(!ToRegister(right).is(ebx));
|
| @@ -3051,21 +3055,8 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
|
| Register value = ToRegister(instr->value());
|
| switch (array_type) {
|
| case kExternalPixelArray: {
|
| - // Clamp the value to [0..255].
|
| - Register temp = ToRegister(instr->TempAt(0));
|
| - // The dec_b below requires that the clamped value is in a byte
|
| - // register. eax is an arbitrary choice to satisfy this requirement, we
|
| - // hinted the register allocator to give us eax when building the
|
| - // instruction.
|
| - ASSERT(temp.is(eax));
|
| - __ mov(temp, ToRegister(instr->value()));
|
| - NearLabel done;
|
| - __ test(temp, Immediate(0xFFFFFF00));
|
| - __ j(zero, &done);
|
| - __ setcc(negative, temp); // 1 if negative, 0 if positive.
|
| - __ dec_b(temp); // 0 if negative, 255 if positive.
|
| - __ bind(&done);
|
| - __ mov_b(Operand(external_pointer, key, times_1, 0), temp);
|
| + ASSERT(value.is(eax));
|
| + __ mov_b(Operand(external_pointer, key, times_1, 0), value);
|
| break;
|
| }
|
| case kExternalByteArray:
|
| @@ -3282,7 +3273,7 @@ void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
|
| DeferredStringCharFromCode* deferred =
|
| new DeferredStringCharFromCode(this, instr);
|
|
|
| - ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
|
| + ASSERT(instr->hydrogen()->value()->representation().IsInteger());
|
| Register char_code = ToRegister(instr->char_code());
|
| Register result = ToRegister(instr->result());
|
| ASSERT(!char_code.is(result));
|
| @@ -3348,6 +3339,15 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoInteger32ToClamped(LInteger32ToClamped* instr) {
|
| + LOperand* input = instr->InputAt(0);
|
| + ASSERT(input->IsRegister());
|
| + Register reg = ToRegister(input);
|
| + ASSERT(reg.is(ToRegister(instr->result())));
|
| + __ ClampUInt8(reg);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
|
| class DeferredNumberTagI: public LDeferredCode {
|
| public:
|
| @@ -3461,7 +3461,12 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
| __ test(ToRegister(input), Immediate(kSmiTagMask));
|
| DeoptimizeIf(not_zero, instr->environment());
|
| }
|
| - __ SmiUntag(ToRegister(input));
|
| + Register input_reg = ToRegister(input);
|
| + __ SmiUntag(input_reg);
|
| +
|
| + if (instr->should_clamp()) {
|
| + __ ClampUInt8(input_reg);
|
| + }
|
| }
|
|
|
|
|
| @@ -3512,14 +3517,30 @@ class DeferredTaggedToI: public LDeferredCode {
|
|
|
|
|
| void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
| - NearLabel done, heap_number;
|
| + NearLabel done;
|
| Register input_reg = ToRegister(instr->InputAt(0));
|
|
|
| // Heap number map check.
|
| __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
| factory()->heap_number_map());
|
|
|
| - if (instr->truncating()) {
|
| + Representation r = instr->hydrogen()->representation();
|
| + if (r.IsClampedRoundedInteger8()) {
|
| + NearLabel heap_number;
|
| + __ j(equal, &heap_number);
|
| + // Check for undefined. Undefined is converted to zero for truncating
|
| + // conversions.
|
| + __ cmp(input_reg, factory()->undefined_value());
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| + __ mov(input_reg, 0);
|
| + __ jmp(&done);
|
| +
|
| + __ bind(&heap_number);
|
| + XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
|
| + __ movdbl(xmm_temp, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
| + __ ClampDoubleToUInt8(xmm_temp, input_reg);
|
| + } else if (r.IsTruncatedInteger32()) {
|
| + NearLabel heap_number;
|
| __ j(equal, &heap_number);
|
| // Check for undefined. Undefined is converted to zero for truncating
|
| // conversions.
|
| @@ -3607,6 +3628,10 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
|
|
|
| // Smi to int32 conversion
|
| __ SmiUntag(input_reg); // Untag smi.
|
| + Representation r = instr->hydrogen()->representation();
|
| + if (r.IsClampedRoundedInteger8()) {
|
| + __ ClampUInt8(input_reg);
|
| + }
|
|
|
| __ bind(deferred->exit());
|
| }
|
| @@ -3634,7 +3659,10 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
|
| XMMRegister input_reg = ToDoubleRegister(input);
|
| Register result_reg = ToRegister(result);
|
|
|
| - if (instr->truncating()) {
|
| + Representation r = instr->hydrogen()->representation();
|
| + if (r.IsClampedRoundedInteger8()) {
|
| + __ ClampDoubleToUInt8(input_reg, result_reg);
|
| + } else if (r.IsTruncatedInteger32()) {
|
| // Performs a truncating conversion of a floating point number as used by
|
| // the JS bitwise operations.
|
| __ cvttsd2si(result_reg, Operand(input_reg));
|
|
|