| Index: src/x64/lithium-codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/lithium-codegen-x64.cc (revision 7161)
|
| +++ src/x64/lithium-codegen-x64.cc (working copy)
|
| @@ -752,41 +752,65 @@
|
|
|
|
|
| void LCodeGen::DoModI(LModI* instr) {
|
| - LOperand* right = instr->InputAt(1);
|
| - ASSERT(ToRegister(instr->result()).is(rdx));
|
| - ASSERT(ToRegister(instr->InputAt(0)).is(rax));
|
| - ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
|
| - ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
|
| + if (instr->hydrogen()->HasPowerOf2Divisor()) {
|
| + Register dividend = ToRegister(instr->InputAt(0));
|
|
|
| - Register right_reg = ToRegister(right);
|
| + int32_t divisor =
|
| + HConstant::cast(instr->hydrogen()->right())->Integer32Value();
|
|
|
| - // Check for x % 0.
|
| - if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
|
| - __ testl(right_reg, right_reg);
|
| - DeoptimizeIf(zero, instr->environment());
|
| - }
|
| + if (divisor < 0) divisor = -divisor;
|
|
|
| - // Sign extend eax to edx. (We are using only the low 32 bits of the values.)
|
| - __ cdq();
|
| + NearLabel positive_dividend, done;
|
| + __ testl(dividend, dividend);
|
| + __ j(not_sign, &positive_dividend);
|
| + __ negl(dividend);
|
| + __ andl(dividend, Immediate(divisor - 1));
|
| + __ negl(dividend);
|
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| + __ j(not_zero, &done);
|
| + DeoptimizeIf(no_condition, instr->environment());
|
| + }
|
| + __ bind(&positive_dividend);
|
| + __ andl(dividend, Immediate(divisor - 1));
|
| + __ bind(&done);
|
| + } else {
|
| + LOperand* right = instr->InputAt(1);
|
| + Register right_reg = ToRegister(right);
|
|
|
| - // Check for (0 % -x) that will produce negative zero.
|
| - if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| - NearLabel positive_left;
|
| - NearLabel done;
|
| - __ testl(rax, rax);
|
| - __ j(not_sign, &positive_left);
|
| - __ idivl(right_reg);
|
| + ASSERT(ToRegister(instr->result()).is(rdx));
|
| + ASSERT(ToRegister(instr->InputAt(0)).is(rax));
|
| + ASSERT(!right_reg.is(rax));
|
| + ASSERT(!right_reg.is(rdx));
|
|
|
| - // Test the remainder for 0, because then the result would be -0.
|
| - __ testl(rdx, rdx);
|
| - __ j(not_zero, &done);
|
| + // Check for x % 0.
|
| + if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
|
| + __ testl(right_reg, right_reg);
|
| + DeoptimizeIf(zero, instr->environment());
|
| + }
|
|
|
| - DeoptimizeIf(no_condition, instr->environment());
|
| - __ bind(&positive_left);
|
| - __ idivl(right_reg);
|
| - __ bind(&done);
|
| - } else {
|
| - __ idivl(right_reg);
|
| + // Sign extend eax to edx.
|
| + // (We are using only the low 32 bits of the values.)
|
| + __ cdq();
|
| +
|
| + // Check for (0 % -x) that will produce negative zero.
|
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| + NearLabel positive_left;
|
| + NearLabel done;
|
| + __ testl(rax, rax);
|
| + __ j(not_sign, &positive_left);
|
| + __ idivl(right_reg);
|
| +
|
| + // Test the remainder for 0, because then the result would be -0.
|
| + __ testl(rdx, rdx);
|
| + __ j(not_zero, &done);
|
| +
|
| + DeoptimizeIf(no_condition, instr->environment());
|
| + __ bind(&positive_left);
|
| + __ idivl(right_reg);
|
| + __ bind(&done);
|
| + } else {
|
| + __ idivl(right_reg);
|
| + }
|
| }
|
| }
|
|
|
| @@ -1059,7 +1083,7 @@
|
| void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
|
| Register result = ToRegister(instr->result());
|
| Register array = ToRegister(instr->InputAt(0));
|
| - __ movq(result, FieldOperand(array, ExternalPixelArray::kLengthOffset));
|
| + __ movl(result, FieldOperand(array, ExternalPixelArray::kLengthOffset));
|
| }
|
|
|
|
|
| @@ -1210,7 +1234,7 @@
|
| Register reg = ToRegister(instr->InputAt(0));
|
| HType type = instr->hydrogen()->type();
|
| if (type.IsBoolean()) {
|
| - __ Cmp(reg, Factory::true_value());
|
| + __ CompareRoot(reg, Heap::kTrueValueRootIndex);
|
| EmitBranch(true_block, false_block, equal);
|
| } else if (type.IsSmi()) {
|
| __ SmiCompare(reg, Smi::FromInt(0));
|
| @@ -1477,14 +1501,14 @@
|
|
|
| int true_block = chunk_->LookupDestination(instr->true_block_id());
|
|
|
| - __ Cmp(reg, Factory::null_value());
|
| + __ CompareRoot(reg, Heap::kNullValueRootIndex);
|
| if (instr->is_strict()) {
|
| EmitBranch(true_block, false_block, equal);
|
| } else {
|
| Label* true_label = chunk_->GetAssemblyLabel(true_block);
|
| Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
| __ j(equal, true_label);
|
| - __ Cmp(reg, Factory::undefined_value());
|
| + __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
|
| __ j(equal, true_label);
|
| __ JumpIfSmi(reg, false_label);
|
| // Check for undetectable objects by looking in the bit field in
|
| @@ -2092,14 +2116,14 @@
|
| __ movq(result, FieldOperand(input, JSObject::kElementsOffset));
|
| if (FLAG_debug_code) {
|
| NearLabel done;
|
| - __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
|
| - Factory::fixed_array_map());
|
| + __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
|
| + Heap::kFixedArrayMapRootIndex);
|
| __ j(equal, &done);
|
| - __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
|
| - Factory::external_pixel_array_map());
|
| + __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
|
| + Heap::kExternalPixelArrayMapRootIndex);
|
| __ j(equal, &done);
|
| - __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
|
| - Factory::fixed_cow_array_map());
|
| + __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
|
| + Heap::kFixedCOWArrayMapRootIndex);
|
| __ Check(equal, "Check for fast elements failed.");
|
| __ bind(&done);
|
| }
|
| @@ -2146,7 +2170,7 @@
|
| FixedArray::kHeaderSize));
|
|
|
| // Check for the hole value.
|
| - __ Cmp(result, Factory::the_hole_value());
|
| + __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
|
| DeoptimizeIf(equal, instr->environment());
|
| }
|
|
|
| @@ -2978,6 +3002,56 @@
|
| }
|
|
|
|
|
| +void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
|
| + class DeferredStringCharFromCode: public LDeferredCode {
|
| + public:
|
| + DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
|
| + : LDeferredCode(codegen), instr_(instr) { }
|
| + virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
|
| + private:
|
| + LStringCharFromCode* instr_;
|
| + };
|
| +
|
| + DeferredStringCharFromCode* deferred =
|
| + new DeferredStringCharFromCode(this, instr);
|
| +
|
| + ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
|
| + Register char_code = ToRegister(instr->char_code());
|
| + Register result = ToRegister(instr->result());
|
| + ASSERT(!char_code.is(result));
|
| +
|
| + __ cmpl(char_code, Immediate(String::kMaxAsciiCharCode));
|
| + __ j(above, deferred->entry());
|
| + __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
|
| + __ movq(result, FieldOperand(result,
|
| + char_code, times_pointer_size,
|
| + FixedArray::kHeaderSize));
|
| + __ CompareRoot(result, Heap::kUndefinedValueRootIndex);
|
| + __ j(equal, deferred->entry());
|
| + __ bind(deferred->exit());
|
| +}
|
| +
|
| +
|
| +void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
|
| + Register char_code = ToRegister(instr->char_code());
|
| + Register result = ToRegister(instr->result());
|
| +
|
| + // TODO(3095996): Get rid of this. For now, we need to make the
|
| + // result register contain a valid pointer because it is already
|
| + // contained in the register pointer map.
|
| + __ Set(result, 0);
|
| +
|
| + __ PushSafepointRegisters();
|
| + __ Integer32ToSmi(char_code, char_code);
|
| + __ push(char_code);
|
| + __ CallRuntimeSaveDoubles(Runtime::kCharFromCode);
|
| + RecordSafepointWithRegisters(
|
| + instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex);
|
| + __ StoreToSafepointRegisterSlot(result, rax);
|
| + __ PopSafepointRegisters();
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoStringLength(LStringLength* instr) {
|
| Register string = ToRegister(instr->string());
|
| Register result = ToRegister(instr->result());
|
| @@ -3434,7 +3508,9 @@
|
| } else {
|
| __ push(rsi);
|
| __ Push(shared_info);
|
| - __ Push(pretenure ? Factory::true_value() : Factory::false_value());
|
| + __ PushRoot(pretenure ?
|
| + Heap::kTrueValueRootIndex :
|
| + Heap::kFalseValueRootIndex);
|
| CallRuntime(Runtime::kNewClosure, 3, instr);
|
| }
|
| }
|
| @@ -3517,8 +3593,9 @@
|
| Condition final_branch_condition = no_condition;
|
| if (type_name->Equals(Heap::number_symbol())) {
|
| __ JumpIfSmi(input, true_label);
|
| - __ Cmp(FieldOperand(input, HeapObject::kMapOffset),
|
| - Factory::heap_number_map());
|
| + __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset),
|
| + Heap::kHeapNumberMapRootIndex);
|
| +
|
| final_branch_condition = equal;
|
|
|
| } else if (type_name->Equals(Heap::string_symbol())) {
|
|
|