Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: src/ia32/lithium-codegen-ia32.cc

Issue 7060010: Merge bleeding edge into the GC branch up to 7948. The asserts (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/lithium-codegen-ia32.cc
===================================================================
--- src/ia32/lithium-codegen-ia32.cc (revision 7948)
+++ src/ia32/lithium-codegen-ia32.cc (working copy)
@@ -546,7 +546,7 @@
__ mov(ebx, shared);
__ mov(eax, FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset));
__ sub(Operand(eax), Immediate(Smi::FromInt(1)));
- __ j(not_zero, &no_deopt);
+ __ j(not_zero, &no_deopt, Label::kNear);
if (FLAG_trap_on_deopt) __ int3();
__ mov(eax, Immediate(Smi::FromInt(FLAG_deopt_every_n_times)));
__ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax);
@@ -567,13 +567,13 @@
__ jmp(entry, RelocInfo::RUNTIME_ENTRY);
} else {
if (FLAG_trap_on_deopt) {
- NearLabel done;
- __ j(NegateCondition(cc), &done);
+ Label done;
+ __ j(NegateCondition(cc), &done, Label::kNear);
__ int3();
__ jmp(entry, RelocInfo::RUNTIME_ENTRY);
__ bind(&done);
} else {
- __ j(cc, entry, RelocInfo::RUNTIME_ENTRY, not_taken);
+ __ j(cc, entry, RelocInfo::RUNTIME_ENTRY);
}
}
}
@@ -788,21 +788,21 @@
if (divisor < 0) divisor = -divisor;
- NearLabel positive_dividend, done;
+ Label positive_dividend, done;
__ test(dividend, Operand(dividend));
- __ j(not_sign, &positive_dividend);
+ __ j(not_sign, &positive_dividend, Label::kNear);
__ neg(dividend);
__ and_(dividend, divisor - 1);
__ neg(dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- __ j(not_zero, &done);
+ __ j(not_zero, &done, Label::kNear);
DeoptimizeIf(no_condition, instr->environment());
}
__ bind(&positive_dividend);
__ and_(dividend, divisor - 1);
__ bind(&done);
} else {
- NearLabel done, remainder_eq_dividend, slow, do_subtraction, both_positive;
+ Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
Register left_reg = ToRegister(instr->InputAt(0));
Register right_reg = ToRegister(instr->InputAt(1));
Register result_reg = ToRegister(instr->result());
@@ -819,11 +819,11 @@
}
__ test(left_reg, Operand(left_reg));
- __ j(zero, &remainder_eq_dividend);
- __ j(sign, &slow);
+ __ j(zero, &remainder_eq_dividend, Label::kNear);
+ __ j(sign, &slow, Label::kNear);
__ test(right_reg, Operand(right_reg));
- __ j(not_sign, &both_positive);
+ __ j(not_sign, &both_positive, Label::kNear);
// The sign of the divisor doesn't matter.
__ neg(right_reg);
@@ -831,16 +831,16 @@
// If the dividend is smaller than the nonnegative
// divisor, the dividend is the result.
__ cmp(left_reg, Operand(right_reg));
- __ j(less, &remainder_eq_dividend);
+ __ j(less, &remainder_eq_dividend, Label::kNear);
// Check if the divisor is a PowerOfTwo integer.
Register scratch = ToRegister(instr->TempAt(0));
__ mov(scratch, right_reg);
__ sub(Operand(scratch), Immediate(1));
__ test(scratch, Operand(right_reg));
- __ j(not_zero, &do_subtraction);
+ __ j(not_zero, &do_subtraction, Label::kNear);
__ and_(left_reg, Operand(scratch));
- __ jmp(&remainder_eq_dividend);
+ __ jmp(&remainder_eq_dividend, Label::kNear);
__ bind(&do_subtraction);
const int kUnfolds = 3;
@@ -851,7 +851,7 @@
__ sub(left_reg, Operand(right_reg));
// Check if the dividend is less than the divisor.
__ cmp(left_reg, Operand(right_reg));
- __ j(less, &remainder_eq_dividend);
+ __ j(less, &remainder_eq_dividend, Label::kNear);
}
__ mov(left_reg, scratch);
@@ -862,15 +862,15 @@
// Check for (0 % -x) that will produce negative zero.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- NearLabel positive_left;
- NearLabel done;
+ Label positive_left;
+ Label done;
__ test(left_reg, Operand(left_reg));
- __ j(not_sign, &positive_left);
+ __ j(not_sign, &positive_left, Label::kNear);
__ idiv(right_reg);
// Test the remainder for 0, because then the result would be -0.
__ test(result_reg, Operand(result_reg));
- __ j(not_zero, &done);
+ __ j(not_zero, &done, Label::kNear);
DeoptimizeIf(no_condition, instr->environment());
__ bind(&positive_left);
@@ -879,7 +879,7 @@
} else {
__ idiv(right_reg);
}
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&remainder_eq_dividend);
__ mov(result_reg, left_reg);
@@ -907,9 +907,9 @@
// Check for (0 / -x) that will produce negative zero.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- NearLabel left_not_zero;
+ Label left_not_zero;
__ test(left_reg, Operand(left_reg));
- __ j(not_zero, &left_not_zero);
+ __ j(not_zero, &left_not_zero, Label::kNear);
__ test(right_reg, ToOperand(right));
DeoptimizeIf(sign, instr->environment());
__ bind(&left_not_zero);
@@ -917,9 +917,9 @@
// Check for (-kMinInt / -1).
if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
- NearLabel left_not_min_int;
+ Label left_not_min_int;
__ cmp(left_reg, kMinInt);
- __ j(not_zero, &left_not_min_int);
+ __ j(not_zero, &left_not_min_int, Label::kNear);
__ cmp(right_reg, -1);
DeoptimizeIf(zero, instr->environment());
__ bind(&left_not_min_int);
@@ -997,9 +997,9 @@
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Bail out if the result is supposed to be negative zero.
- NearLabel done;
+ Label done;
__ test(left, Operand(left));
- __ j(not_zero, &done);
+ __ j(not_zero, &done, Label::kNear);
if (right->IsConstantOperand()) {
if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
DeoptimizeIf(no_condition, instr->environment());
@@ -1204,14 +1204,14 @@
Register result = ToRegister(instr->result());
Register map = ToRegister(instr->TempAt(0));
ASSERT(input.is(result));
- NearLabel done;
+ Label done;
// If the object is a smi return the object.
__ test(input, Immediate(kSmiTagMask));
- __ j(zero, &done);
+ __ j(zero, &done, Label::kNear);
// If the object is not a value type, return the object.
__ CmpObjectType(input, JS_VALUE_TYPE, map);
- __ j(not_equal, &done);
+ __ j(not_equal, &done, Label::kNear);
__ mov(result, FieldOperand(input, JSValue::kValueOffset));
__ bind(&done);
@@ -1369,10 +1369,10 @@
__ j(zero, true_label);
// Test for double values. Zero is false.
- NearLabel call_stub;
+ Label call_stub;
__ cmp(FieldOperand(reg, HeapObject::kMapOffset),
factory()->heap_number_map());
- __ j(not_equal, &call_stub);
+ __ j(not_equal, &call_stub, Label::kNear);
__ fldz();
__ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
__ FCmp();
@@ -1478,20 +1478,20 @@
LOperand* right = instr->InputAt(1);
LOperand* result = instr->result();
- NearLabel unordered;
+ Label unordered;
if (instr->is_double()) {
// Don't base result on EFLAGS when a NaN is involved. Instead
// jump to the unordered case, which produces a false value.
__ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
- __ j(parity_even, &unordered, not_taken);
+ __ j(parity_even, &unordered, Label::kNear);
} else {
EmitCmpI(left, right);
}
- NearLabel done;
+ Label done;
Condition cc = TokenToCondition(instr->op(), instr->is_double());
__ mov(ToRegister(result), factory()->true_value());
- __ j(cc, &done);
+ __ j(cc, &done, Label::kNear);
__ bind(&unordered);
__ mov(ToRegister(result), factory()->false_value());
@@ -1526,8 +1526,8 @@
__ cmp(left, Operand(right));
__ mov(result, factory()->true_value());
- NearLabel done;
- __ j(equal, &done);
+ Label done;
+ __ j(equal, &done, Label::kNear);
__ mov(result, factory()->false_value());
__ bind(&done);
}
@@ -1544,6 +1544,31 @@
}
+void LCodeGen::DoCmpSymbolEq(LCmpSymbolEq* instr) {
+ Register left = ToRegister(instr->InputAt(0));
+ Register right = ToRegister(instr->InputAt(1));
+ Register result = ToRegister(instr->result());
+
+ Label done;
+ __ cmp(left, Operand(right));
+ __ mov(result, factory()->false_value());
+ __ j(not_equal, &done, Label::kNear);
+ __ mov(result, factory()->true_value());
+ __ bind(&done);
+}
+
+
+void LCodeGen::DoCmpSymbolEqAndBranch(LCmpSymbolEqAndBranch* instr) {
+ Register left = ToRegister(instr->InputAt(0));
+ Register right = ToRegister(instr->InputAt(1));
+ int false_block = chunk_->LookupDestination(instr->false_block_id());
+ int true_block = chunk_->LookupDestination(instr->true_block_id());
+
+ __ cmp(left, Operand(right));
+ EmitBranch(true_block, false_block, equal);
+}
+
+
void LCodeGen::DoIsNull(LIsNull* instr) {
Register reg = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
@@ -1554,27 +1579,27 @@
__ cmp(reg, factory()->null_value());
if (instr->is_strict()) {
__ mov(result, factory()->true_value());
- NearLabel done;
- __ j(equal, &done);
+ Label done;
+ __ j(equal, &done, Label::kNear);
__ mov(result, factory()->false_value());
__ bind(&done);
} else {
- NearLabel true_value, false_value, done;
- __ j(equal, &true_value);
+ Label true_value, false_value, done;
+ __ j(equal, &true_value, Label::kNear);
__ cmp(reg, factory()->undefined_value());
- __ j(equal, &true_value);
+ __ j(equal, &true_value, Label::kNear);
__ test(reg, Immediate(kSmiTagMask));
- __ j(zero, &false_value);
+ __ j(zero, &false_value, Label::kNear);
// Check for undetectable objects by looking in the bit field in
// the map. The object has already been smi checked.
Register scratch = result;
__ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
__ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
__ test(scratch, Immediate(1 << Map::kIsUndetectable));
- __ j(not_zero, &true_value);
+ __ j(not_zero, &true_value, Label::kNear);
__ bind(&false_value);
__ mov(result, factory()->false_value());
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&true_value);
__ mov(result, factory()->true_value());
__ bind(&done);
@@ -1685,8 +1710,8 @@
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
__ test(input, Immediate(kSmiTagMask));
__ mov(result, factory()->true_value());
- NearLabel done;
- __ j(zero, &done);
+ Label done;
+ __ j(zero, &done, Label::kNear);
__ mov(result, factory()->false_value());
__ bind(&done);
}
@@ -1703,6 +1728,44 @@
}
+void LCodeGen::DoIsUndetectable(LIsUndetectable* instr) {
+ Register input = ToRegister(instr->InputAt(0));
+ Register result = ToRegister(instr->result());
+
+ ASSERT(instr->hydrogen()->value()->representation().IsTagged());
+ Label false_label, done;
+ STATIC_ASSERT(kSmiTag == 0);
+ __ test(input, Immediate(kSmiTagMask));
+ __ j(zero, &false_label, Label::kNear);
+ __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
+ __ test_b(FieldOperand(result, Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
+ __ j(zero, &false_label, Label::kNear);
+ __ mov(result, factory()->true_value());
+ __ jmp(&done);
+ __ bind(&false_label);
+ __ mov(result, factory()->false_value());
+ __ bind(&done);
+}
+
+
+void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
+ Register input = ToRegister(instr->InputAt(0));
+ Register temp = ToRegister(instr->TempAt(0));
+
+ int true_block = chunk_->LookupDestination(instr->true_block_id());
+ int false_block = chunk_->LookupDestination(instr->false_block_id());
+
+ STATIC_ASSERT(kSmiTag == 0);
+ __ test(input, Immediate(kSmiTagMask));
+ __ j(zero, chunk_->GetAssemblyLabel(false_block));
+ __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
+ __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
+ EmitBranch(true_block, false_block, not_zero);
+}
+
+
static InstanceType TestType(HHasInstanceType* instr) {
InstanceType from = instr->from();
InstanceType to = instr->to();
@@ -1729,12 +1792,13 @@
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
__ test(input, Immediate(kSmiTagMask));
- NearLabel done, is_false;
- __ j(zero, &is_false);
+ Label done, is_false;
+ __ j(zero, &is_false, Label::kNear);
__ CmpObjectType(input, TestType(instr->hydrogen()), result);
- __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
+ __ j(NegateCondition(BranchCondition(instr->hydrogen())),
+ &is_false, Label::kNear);
__ mov(result, factory()->true_value());
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&is_false);
__ mov(result, factory()->false_value());
__ bind(&done);
@@ -1779,8 +1843,8 @@
__ mov(result, factory()->true_value());
__ test(FieldOperand(input, String::kHashFieldOffset),
Immediate(String::kContainsCachedArrayIndexMask));
- NearLabel done;
- __ j(zero, &done);
+ Label done;
+ __ j(zero, &done, Label::kNear);
__ mov(result, factory()->false_value());
__ bind(&done);
}
@@ -1862,16 +1926,16 @@
ASSERT(input.is(result));
Register temp = ToRegister(instr->TempAt(0));
Handle<String> class_name = instr->hydrogen()->class_name();
- NearLabel done;
+ Label done;
Label is_true, is_false;
EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input);
- __ j(not_equal, &is_false);
+ __ j(not_equal, &is_false, Label::kNear);
__ bind(&is_true);
__ mov(result, factory()->true_value());
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&is_false);
__ mov(result, factory()->false_value());
@@ -1919,11 +1983,11 @@
InstanceofStub stub(InstanceofStub::kArgsInRegisters);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
- NearLabel true_value, done;
+ Label true_value, done;
__ test(eax, Operand(eax));
- __ j(zero, &true_value);
+ __ j(zero, &true_value, Label::kNear);
__ mov(ToRegister(instr->result()), factory()->false_value());
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&true_value);
__ mov(ToRegister(instr->result()), factory()->true_value());
__ bind(&done);
@@ -1968,17 +2032,17 @@
// A Smi is not an instance of anything.
__ test(object, Immediate(kSmiTagMask));
- __ j(zero, &false_result, not_taken);
+ __ j(zero, &false_result);
// This is the inlined call site instanceof cache. The two occurences of the
// hole value will be patched to the last map/result pair generated by the
// instanceof stub.
- NearLabel cache_miss;
+ Label cache_miss;
Register map = ToRegister(instr->TempAt(0));
__ mov(map, FieldOperand(object, HeapObject::kMapOffset));
__ bind(deferred->map_check()); // Label for calculating code patching.
__ cmp(map, factory()->the_hole_value()); // Patched to cached map.
- __ j(not_equal, &cache_miss, not_taken);
+ __ j(not_equal, &cache_miss, Label::kNear);
__ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
__ jmp(&done);
@@ -2070,11 +2134,11 @@
if (op == Token::GT || op == Token::LTE) {
condition = ReverseCondition(condition);
}
- NearLabel true_value, done;
+ Label true_value, done;
__ test(eax, Operand(eax));
- __ j(condition, &true_value);
+ __ j(condition, &true_value, Label::kNear);
__ mov(ToRegister(instr->result()), factory()->false_value());
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&true_value);
__ mov(ToRegister(instr->result()), factory()->true_value());
__ bind(&done);
@@ -2254,23 +2318,23 @@
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
} else {
- NearLabel done;
+ Label done;
for (int i = 0; i < map_count - 1; ++i) {
Handle<Map> map = instr->hydrogen()->types()->at(i);
- NearLabel next;
+ Label next;
__ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
- __ j(not_equal, &next);
+ __ j(not_equal, &next, Label::kNear);
EmitLoadFieldOrConstantFunction(result, object, map, name);
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&next);
}
Handle<Map> map = instr->hydrogen()->types()->last();
__ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
if (instr->hydrogen()->need_generic()) {
- NearLabel generic;
- __ j(not_equal, &generic);
+ Label generic;
+ __ j(not_equal, &generic, Label::kNear);
EmitLoadFieldOrConstantFunction(result, object, map, name);
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&generic);
__ mov(ecx, name);
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
@@ -2305,10 +2369,10 @@
DeoptimizeIf(not_equal, instr->environment());
// Check whether the function has an instance prototype.
- NearLabel non_instance;
+ Label non_instance;
__ test_b(FieldOperand(result, Map::kBitFieldOffset),
1 << Map::kHasNonInstancePrototype);
- __ j(not_zero, &non_instance);
+ __ j(not_zero, &non_instance, Label::kNear);
// Get the prototype or initial map from the function.
__ mov(result,
@@ -2319,13 +2383,13 @@
DeoptimizeIf(equal, instr->environment());
// If the function does not have an initial map, we're done.
- NearLabel done;
+ Label done;
__ CmpObjectType(result, MAP_TYPE, temp);
- __ j(not_equal, &done);
+ __ j(not_equal, &done, Label::kNear);
// Get the prototype from the initial map.
__ mov(result, FieldOperand(result, Map::kPrototypeOffset));
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
// Non-instance prototype: Fetch prototype from constructor field
// in the function's map.
@@ -2342,13 +2406,13 @@
Register input = ToRegister(instr->InputAt(0));
__ mov(result, FieldOperand(input, JSObject::kElementsOffset));
if (FLAG_debug_code) {
- NearLabel done;
+ Label done;
__ cmp(FieldOperand(result, HeapObject::kMapOffset),
Immediate(factory()->fixed_array_map()));
- __ j(equal, &done);
+ __ j(equal, &done, Label::kNear);
__ cmp(FieldOperand(result, HeapObject::kMapOffset),
Immediate(factory()->fixed_cow_array_map()));
- __ j(equal, &done);
+ __ j(equal, &done, Label::kNear);
Register temp((result.is(eax)) ? ebx : eax);
__ push(temp);
__ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
@@ -2399,44 +2463,63 @@
FixedArray::kHeaderSize));
// Check for the hole value.
- __ cmp(result, factory()->the_hole_value());
- DeoptimizeIf(equal, instr->environment());
+ if (instr->hydrogen()->RequiresHoleCheck()) {
+ __ cmp(result, factory()->the_hole_value());
+ DeoptimizeIf(equal, instr->environment());
+ }
}
+Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer,
+ LOperand* key,
+ ExternalArrayType array_type) {
+ Register external_pointer_reg = ToRegister(external_pointer);
+ int shift_size = ExternalArrayTypeToShiftSize(array_type);
+ if (key->IsConstantOperand()) {
+ int constant_value = ToInteger32(LConstantOperand::cast(key));
+ if (constant_value & 0xF0000000) {
+ Abort("array index constant value too big");
+ }
+ return Operand(external_pointer_reg, constant_value * (1 << shift_size));
+ } else {
+ ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
+ return Operand(external_pointer_reg, ToRegister(key), scale_factor, 0);
+ }
+}
+
+
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
- Register external_pointer = ToRegister(instr->external_pointer());
- Register key = ToRegister(instr->key());
ExternalArrayType array_type = instr->array_type();
+ Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
+ instr->key(), array_type));
if (array_type == kExternalFloatArray) {
XMMRegister result(ToDoubleRegister(instr->result()));
- __ movss(result, Operand(external_pointer, key, times_4, 0));
+ __ movss(result, operand);
__ cvtss2sd(result, result);
} else if (array_type == kExternalDoubleArray) {
- __ movdbl(ToDoubleRegister(instr->result()),
- Operand(external_pointer, key, times_8, 0));
+ __ movdbl(ToDoubleRegister(instr->result()), operand);
} else {
Register result(ToRegister(instr->result()));
switch (array_type) {
case kExternalByteArray:
- __ movsx_b(result, Operand(external_pointer, key, times_1, 0));
+ __ movsx_b(result, operand);
break;
case kExternalUnsignedByteArray:
case kExternalPixelArray:
- __ movzx_b(result, Operand(external_pointer, key, times_1, 0));
+ __ movzx_b(result, operand);
break;
case kExternalShortArray:
- __ movsx_w(result, Operand(external_pointer, key, times_2, 0));
+ __ movsx_w(result, operand);
break;
case kExternalUnsignedShortArray:
- __ movzx_w(result, Operand(external_pointer, key, times_2, 0));
+ __ movzx_w(result, operand);
break;
case kExternalIntArray:
- __ mov(result, Operand(external_pointer, key, times_4, 0));
+ __ mov(result, operand);
break;
case kExternalUnsignedIntArray:
- __ mov(result, Operand(external_pointer, key, times_4, 0));
+ __ mov(result, operand);
__ test(result, Operand(result));
// TODO(danno): we could be more clever here, perhaps having a special
// version of the stub that detects if the overflow case actually
@@ -2466,16 +2549,16 @@
Register result = ToRegister(instr->result());
// Check for arguments adapter frame.
- NearLabel done, adapted;
+ Label done, adapted;
__ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
__ mov(result, Operand(result, StandardFrameConstants::kContextOffset));
__ cmp(Operand(result),
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
- __ j(equal, &adapted);
+ __ j(equal, &adapted, Label::kNear);
// No arguments adaptor frame.
__ mov(result, Operand(ebp));
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
// Arguments adaptor frame present.
__ bind(&adapted);
@@ -2491,12 +2574,12 @@
Operand elem = ToOperand(instr->InputAt(0));
Register result = ToRegister(instr->result());
- NearLabel done;
+ Label done;
// If no arguments adaptor frame the number of arguments is fixed.
__ cmp(ebp, elem);
__ mov(result, Immediate(scope()->num_parameters()));
- __ j(equal, &done);
+ __ j(equal, &done, Label::kNear);
// Arguments adaptor frame present. Get argument length from there.
__ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
@@ -2521,18 +2604,18 @@
// If the receiver is null or undefined, we have to pass the global object
// as a receiver.
- NearLabel global_object, receiver_ok;
+ Label global_object, receiver_ok;
__ cmp(receiver, factory()->null_value());
- __ j(equal, &global_object);
+ __ j(equal, &global_object, Label::kNear);
__ cmp(receiver, factory()->undefined_value());
- __ j(equal, &global_object);
+ __ j(equal, &global_object, Label::kNear);
// The receiver should be a JS object.
__ test(receiver, Immediate(kSmiTagMask));
DeoptimizeIf(equal, instr->environment());
__ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch);
DeoptimizeIf(below, instr->environment());
- __ jmp(&receiver_ok);
+ __ jmp(&receiver_ok, Label::kNear);
__ bind(&global_object);
// TODO(kmillikin): We have a hydrogen value for the global object. See
@@ -2553,10 +2636,10 @@
// Loop through the arguments pushing them onto the execution
// stack.
- NearLabel invoke, loop;
+ Label invoke, loop;
// length is a small non-negative integer, due to the test above.
__ test(length, Operand(length));
- __ j(zero, &invoke);
+ __ j(zero, &invoke, Label::kNear);
__ bind(&loop);
__ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
__ dec(length);
@@ -2908,20 +2991,20 @@
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
ASSERT(instr->InputAt(0)->Equals(instr->result()));
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
- NearLabel positive, done, zero, negative;
+ Label positive, done, zero;
__ xorps(xmm0, xmm0);
__ ucomisd(input_reg, xmm0);
- __ j(above, &positive);
- __ j(equal, &zero);
+ __ j(above, &positive, Label::kNear);
+ __ j(equal, &zero, Label::kNear);
ExternalReference nan = ExternalReference::address_of_nan();
__ movdbl(input_reg, Operand::StaticVariable(nan));
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&zero);
__ push(Immediate(0xFFF00000));
__ push(Immediate(0));
__ movdbl(input_reg, Operand(esp, 0));
__ add(Operand(esp), Immediate(kDoubleSize));
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&positive);
__ fldln2();
__ sub(Operand(esp), Immediate(kDoubleSize));
@@ -3120,47 +3203,29 @@
void LCodeGen::DoStoreKeyedSpecializedArrayElement(
LStoreKeyedSpecializedArrayElement* instr) {
- Register external_pointer = ToRegister(instr->external_pointer());
- Register key = ToRegister(instr->key());
ExternalArrayType array_type = instr->array_type();
+ Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
+ instr->key(), array_type));
if (array_type == kExternalFloatArray) {
__ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
- __ movss(Operand(external_pointer, key, times_4, 0), xmm0);
+ __ movss(operand, xmm0);
} else if (array_type == kExternalDoubleArray) {
- __ movdbl(Operand(external_pointer, key, times_8, 0),
- ToDoubleRegister(instr->value()));
+ __ movdbl(operand, ToDoubleRegister(instr->value()));
} else {
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);
- break;
- }
+ case kExternalPixelArray:
case kExternalByteArray:
case kExternalUnsignedByteArray:
- __ mov_b(Operand(external_pointer, key, times_1, 0), value);
+ __ mov_b(operand, value);
break;
case kExternalShortArray:
case kExternalUnsignedShortArray:
- __ mov_w(Operand(external_pointer, key, times_2, 0), value);
+ __ mov_w(operand, value);
break;
case kExternalIntArray:
case kExternalUnsignedIntArray:
- __ mov(Operand(external_pointer, key, times_4, 0), value);
+ __ mov(operand, value);
break;
case kExternalFloatArray:
case kExternalDoubleArray:
@@ -3250,7 +3315,7 @@
DeferredStringCharCodeAt* deferred =
new DeferredStringCharCodeAt(this, instr);
- NearLabel flat_string, ascii_string, done;
+ Label flat_string, ascii_string, done;
// Fetch the instance type of the receiver into result register.
__ mov(result, FieldOperand(string, HeapObject::kMapOffset));
@@ -3259,7 +3324,7 @@
// We need special handling for non-flat strings.
STATIC_ASSERT(kSeqStringTag == 0);
__ test(result, Immediate(kStringRepresentationMask));
- __ j(zero, &flat_string);
+ __ j(zero, &flat_string, Label::kNear);
// Handle non-flat strings.
__ test(result, Immediate(kIsConsStringMask));
@@ -3286,7 +3351,7 @@
__ bind(&flat_string);
STATIC_ASSERT(kAsciiStringTag != 0);
__ test(result, Immediate(kStringEncodingMask));
- __ j(not_zero, &ascii_string);
+ __ j(not_zero, &ascii_string, Label::kNear);
// Two-byte string.
// Load the two-byte character code into the result register.
@@ -3302,7 +3367,7 @@
times_2,
SeqTwoByteString::kHeaderSize));
}
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
// ASCII string.
// Load the byte into the result register.
@@ -3463,13 +3528,13 @@
// There was overflow, so bits 30 and 31 of the original integer
// disagree. Try to allocate a heap number in new space and store
// the value in there. If that fails, call the runtime system.
- NearLabel done;
+ Label done;
__ SmiUntag(reg);
__ xor_(reg, 0x80000000);
__ cvtsi2sd(xmm0, Operand(reg));
if (FLAG_inline_new) {
__ AllocateHeapNumber(reg, tmp, no_reg, &slow);
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
}
// Slow case: Call the runtime system to do the number allocation.
@@ -3551,16 +3616,16 @@
void LCodeGen::EmitNumberUntagD(Register input_reg,
XMMRegister result_reg,
LEnvironment* env) {
- NearLabel load_smi, heap_number, done;
+ Label load_smi, heap_number, done;
// Smi check.
__ test(input_reg, Immediate(kSmiTagMask));
- __ j(zero, &load_smi, not_taken);
+ __ j(zero, &load_smi, Label::kNear);
// Heap number map check.
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
factory()->heap_number_map());
- __ j(equal, &heap_number);
+ __ j(equal, &heap_number, Label::kNear);
__ cmp(input_reg, factory()->undefined_value());
DeoptimizeIf(not_equal, env);
@@ -3568,12 +3633,12 @@
// Convert undefined to NaN.
ExternalReference nan = ExternalReference::address_of_nan();
__ movdbl(result_reg, Operand::StaticVariable(nan));
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
// Heap number to XMM conversion.
__ bind(&heap_number);
__ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
// Smi to XMM conversion
__ bind(&load_smi);
@@ -3595,7 +3660,7 @@
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
- NearLabel done, heap_number;
+ Label done, heap_number;
Register input_reg = ToRegister(instr->InputAt(0));
// Heap number map check.
@@ -3603,18 +3668,18 @@
factory()->heap_number_map());
if (instr->truncating()) {
- __ j(equal, &heap_number);
+ __ j(equal, &heap_number, Label::kNear);
// 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);
+ __ jmp(&done, Label::kNear);
__ bind(&heap_number);
if (CpuFeatures::IsSupported(SSE3)) {
CpuFeatures::Scope scope(SSE3);
- NearLabel convert;
+ Label convert;
// Use more powerful conversion when sse3 is available.
// Load x87 register with heap number.
__ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
@@ -3624,7 +3689,7 @@
const uint32_t kTooBigExponent =
(HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
__ cmp(Operand(input_reg), Immediate(kTooBigExponent));
- __ j(less, &convert);
+ __ j(less, &convert, Label::kNear);
// Pop FPU stack before deoptimizing.
__ ffree(0);
__ fincstp();
@@ -3638,7 +3703,6 @@
__ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
__ add(Operand(esp), Immediate(kDoubleSize));
} else {
- NearLabel deopt;
XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
__ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2si(input_reg, Operand(xmm0));
@@ -3725,8 +3789,8 @@
if (CpuFeatures::IsSupported(SSE3)) {
// This will deoptimize if the exponent of the input in out of range.
CpuFeatures::Scope scope(SSE3);
- NearLabel convert, done;
- __ j(not_equal, &done);
+ Label convert, done;
+ __ j(not_equal, &done, Label::kNear);
__ sub(Operand(esp), Immediate(kDoubleSize));
__ movdbl(Operand(esp, 0), input_reg);
// Get exponent alone and check for too-big exponent.
@@ -3735,7 +3799,7 @@
const uint32_t kTooBigExponent =
(HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
__ cmp(Operand(result_reg), Immediate(kTooBigExponent));
- __ j(less, &convert);
+ __ j(less, &convert, Label::kNear);
__ add(Operand(esp), Immediate(kDoubleSize));
DeoptimizeIf(no_condition, instr->environment());
__ bind(&convert);
@@ -3746,13 +3810,13 @@
__ add(Operand(esp), Immediate(kDoubleSize));
__ bind(&done);
} else {
- NearLabel done;
+ Label done;
Register temp_reg = ToRegister(instr->TempAt(0));
XMMRegister xmm_scratch = xmm0;
// If cvttsd2si succeeded, we're done. Otherwise, we attempt
// manual conversion.
- __ j(not_equal, &done);
+ __ j(not_equal, &done, Label::kNear);
// Get high 32 bits of the input in result_reg and temp_reg.
__ pshufd(xmm_scratch, input_reg, 1);
@@ -3802,7 +3866,7 @@
__ bind(&done);
}
} else {
- NearLabel done;
+ Label done;
__ cvttsd2si(result_reg, Operand(input_reg));
__ cvtsi2sd(xmm0, Operand(result_reg));
__ ucomisd(xmm0, input_reg);
@@ -3812,7 +3876,7 @@
// The integer converted back is equal to the original. We
// only have to test if we got -0 as an input.
__ test(result_reg, Operand(result_reg));
- __ j(not_zero, &done);
+ __ j(not_zero, &done, Label::kNear);
__ movmskpd(result_reg, input_reg);
// Bit 0 contains the sign of the double in input_reg.
// If input was positive, we are ok and return 0, otherwise
@@ -3842,30 +3906,44 @@
void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
Register input = ToRegister(instr->InputAt(0));
Register temp = ToRegister(instr->TempAt(0));
- InstanceType first = instr->hydrogen()->first();
- InstanceType last = instr->hydrogen()->last();
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
- // If there is only one type in the interval check for equality.
- if (first == last) {
+ if (instr->hydrogen()->is_interval_check()) {
+ InstanceType first;
+ InstanceType last;
+ instr->hydrogen()->GetCheckInterval(&first, &last);
+
__ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
static_cast<int8_t>(first));
- DeoptimizeIf(not_equal, instr->environment());
- } else if (first == FIRST_STRING_TYPE && last == LAST_STRING_TYPE) {
- // String has a dedicated bit in instance type.
- __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), kIsNotStringMask);
- DeoptimizeIf(not_zero, instr->environment());
- } else {
- __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
- static_cast<int8_t>(first));
- DeoptimizeIf(below, instr->environment());
- // Omit check for the last type.
- if (last != LAST_TYPE) {
- __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
- static_cast<int8_t>(last));
- DeoptimizeIf(above, instr->environment());
+
+ // If there is only one type in the interval check for equality.
+ if (first == last) {
+ DeoptimizeIf(not_equal, instr->environment());
+ } else {
+ DeoptimizeIf(below, instr->environment());
+ // Omit check for the last type.
+ if (last != LAST_TYPE) {
+ __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
+ static_cast<int8_t>(last));
+ DeoptimizeIf(above, instr->environment());
+ }
}
+ } else {
+ uint8_t mask;
+ uint8_t tag;
+ instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
+
+ if (IsPowerOf2(mask)) {
+ ASSERT(tag == 0 || IsPowerOf2(tag));
+ __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), mask);
+ DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
+ } else {
+ __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
+ __ and_(temp, mask);
+ __ cmpb(Operand(temp), tag);
+ DeoptimizeIf(not_equal, instr->environment());
+ }
}
}
@@ -3888,6 +3966,54 @@
}
+void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
+ XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
+ Register result_reg = ToRegister(instr->result());
+ __ ClampDoubleToUint8(value_reg, xmm0, result_reg);
+}
+
+
+void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
+ ASSERT(instr->unclamped()->Equals(instr->result()));
+ Register value_reg = ToRegister(instr->result());
+ __ ClampUint8(value_reg);
+}
+
+
+void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
+ ASSERT(instr->unclamped()->Equals(instr->result()));
+ Register input_reg = ToRegister(instr->unclamped());
+ Label is_smi, done, heap_number;
+
+ __ JumpIfSmi(input_reg, &is_smi);
+
+ // Check for heap number
+ __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
+ factory()->heap_number_map());
+ __ j(equal, &heap_number, Label::kNear);
+
+ // Check for undefined. Undefined is converted to zero for clamping
+ // conversions.
+ __ cmp(input_reg, factory()->undefined_value());
+ DeoptimizeIf(not_equal, instr->environment());
+ __ mov(input_reg, 0);
+ __ jmp(&done, Label::kNear);
+
+ // Heap number
+ __ bind(&heap_number);
+ __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
+ __ ClampDoubleToUint8(xmm0, xmm1, input_reg);
+ __ jmp(&done, Label::kNear);
+
+ // smi
+ __ bind(&is_smi);
+ __ SmiUntag(input_reg);
+ __ ClampUint8(input_reg);
+
+ __ bind(&done);
+}
+
+
void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) {
if (isolate()->heap()->InNewSpace(*object)) {
Handle<JSGlobalPropertyCell> cell =
@@ -3989,7 +4115,7 @@
void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
- NearLabel materialized;
+ Label materialized;
// Registers will be used as follows:
// edi = JS function.
// ecx = literals array.
@@ -4001,7 +4127,7 @@
instr->hydrogen()->literal_index() * kPointerSize;
__ mov(ebx, FieldOperand(ecx, literal_offset));
__ cmp(ebx, factory()->undefined_value());
- __ j(not_equal, &materialized);
+ __ j(not_equal, &materialized, Label::kNear);
// Create regexp literal using runtime function
// Result will be in eax.
@@ -4077,16 +4203,16 @@
Register result = ToRegister(instr->result());
Label true_label;
Label false_label;
- NearLabel done;
+ Label done;
Condition final_branch_condition = EmitTypeofIs(&true_label,
&false_label,
input,
instr->type_literal());
- __ j(final_branch_condition, &true_label);
+ __ j(final_branch_condition, &true_label, Label::kNear);
__ bind(&false_label);
__ mov(result, factory()->false_value());
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&true_label);
__ mov(result, factory()->true_value());
@@ -4180,15 +4306,14 @@
void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
Register result = ToRegister(instr->result());
- NearLabel true_label;
- NearLabel false_label;
- NearLabel done;
+ Label true_label;
+ Label done;
EmitIsConstructCall(result);
- __ j(equal, &true_label);
+ __ j(equal, &true_label, Label::kNear);
__ mov(result, factory()->false_value());
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
__ bind(&true_label);
__ mov(result, factory()->true_value());
@@ -4212,10 +4337,10 @@
__ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
// Skip the arguments adaptor frame if it exists.
- NearLabel check_frame_marker;
+ Label check_frame_marker;
__ cmp(Operand(temp, StandardFrameConstants::kContextOffset),
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
- __ j(not_equal, &check_frame_marker);
+ __ j(not_equal, &check_frame_marker, Label::kNear);
__ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
// Check the marker in the calling frame.
@@ -4264,11 +4389,11 @@
void LCodeGen::DoStackCheck(LStackCheck* instr) {
// Perform stack overflow check.
- NearLabel done;
+ Label done;
ExternalReference stack_limit =
ExternalReference::address_of_stack_limit(isolate());
__ cmp(esp, Operand::StaticVariable(stack_limit));
- __ j(above_equal, &done);
+ __ j(above_equal, &done, Label::kNear);
StackCheckStub stub;
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698