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

Unified Diff: src/arm/lithium-codegen-arm.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/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/lithium-codegen-arm.cc
===================================================================
--- src/arm/lithium-codegen-arm.cc (revision 7948)
+++ src/arm/lithium-codegen-arm.cc (working copy)
@@ -1620,6 +1620,28 @@
}
+void LCodeGen::DoCmpSymbolEq(LCmpSymbolEq* instr) {
+ Register left = ToRegister(instr->InputAt(0));
+ Register right = ToRegister(instr->InputAt(1));
+ Register result = ToRegister(instr->result());
+
+ __ cmp(left, Operand(right));
+ __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
+ __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
+}
+
+
+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, eq);
+}
+
+
void LCodeGen::DoIsNull(LIsNull* instr) {
Register reg = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
@@ -1774,6 +1796,40 @@
}
+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;
+ __ JumpIfSmi(input, &false_label);
+ __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset));
+ __ ldrb(result, FieldMemOperand(result, Map::kBitFieldOffset));
+ __ tst(result, Operand(1 << Map::kIsUndetectable));
+ __ b(eq, &false_label);
+ __ LoadRoot(result, Heap::kTrueValueRootIndex);
+ __ jmp(&done);
+ __ bind(&false_label);
+ __ LoadRoot(result, Heap::kFalseValueRootIndex);
+ __ 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());
+
+ __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
+ __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset));
+ __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
+ __ tst(temp, Operand(1 << Map::kIsUndetectable));
+ EmitBranch(true_block, false_block, ne);
+}
+
+
static InstanceType TestType(HHasInstanceType* instr) {
InstanceType from = instr->from();
InstanceType to = instr->to();
@@ -2473,49 +2529,67 @@
__ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
// Check for the hole value.
- __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
- __ cmp(result, scratch);
- DeoptimizeIf(eq, instr->environment());
+ if (instr->hydrogen()->RequiresHoleCheck()) {
+ __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
+ __ cmp(result, scratch);
+ DeoptimizeIf(eq, instr->environment());
+ }
}
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
- Register key = ToRegister(instr->key());
+ Register key = no_reg;
ExternalArrayType array_type = instr->array_type();
- if (array_type == kExternalFloatArray) {
+ bool key_is_constant = instr->key()->IsConstantOperand();
+ int constant_key = 0;
+ if (key_is_constant) {
+ constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+ if (constant_key & 0xF0000000) {
+ Abort("array index constant value too big.");
+ }
+ } else {
+ key = ToRegister(instr->key());
+ }
+ int shift_size = ExternalArrayTypeToShiftSize(array_type);
+
+ if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) {
CpuFeatures::Scope scope(VFP3);
DwVfpRegister result(ToDoubleRegister(instr->result()));
- __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
- __ vldr(result.low(), scratch0(), 0);
- __ vcvt_f64_f32(result, result.low());
- } else if (array_type == kExternalDoubleArray) {
- CpuFeatures::Scope scope(VFP3);
- DwVfpRegister result(ToDoubleRegister(instr->result()));
- __ add(scratch0(), external_pointer, Operand(key, LSL, 3));
- __ vldr(result, scratch0(), 0);
+ Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
+ : Operand(key, LSL, shift_size));
+ __ add(scratch0(), external_pointer, operand);
+ if (array_type == kExternalFloatArray) {
+ __ vldr(result.low(), scratch0(), 0);
+ __ vcvt_f64_f32(result, result.low());
+ } else { // i.e. array_type == kExternalDoubleArray
+ __ vldr(result, scratch0(), 0);
+ }
} else {
Register result(ToRegister(instr->result()));
+ MemOperand mem_operand(key_is_constant
+ ? MemOperand(external_pointer, constant_key * (1 << shift_size))
+ : MemOperand(external_pointer, key, LSL, shift_size));
switch (array_type) {
case kExternalByteArray:
- __ ldrsb(result, MemOperand(external_pointer, key));
+ __ ldrsb(result, mem_operand);
break;
case kExternalUnsignedByteArray:
case kExternalPixelArray:
- __ ldrb(result, MemOperand(external_pointer, key));
+ __ ldrb(result, mem_operand);
break;
case kExternalShortArray:
- __ ldrsh(result, MemOperand(external_pointer, key, LSL, 1));
+ __ ldrsh(result, mem_operand);
break;
case kExternalUnsignedShortArray:
- __ ldrh(result, MemOperand(external_pointer, key, LSL, 1));
+ __ ldrh(result, mem_operand);
break;
case kExternalIntArray:
- __ ldr(result, MemOperand(external_pointer, key, LSL, 2));
+ __ ldr(result, mem_operand);
break;
case kExternalUnsignedIntArray:
- __ ldr(result, MemOperand(external_pointer, key, LSL, 2));
+ __ ldr(result, mem_operand);
__ cmp(result, Operand(0x80000000));
// TODO(danno): we could be more clever here, perhaps having a special
// version of the stub that detects if the overflow case actually
@@ -3245,39 +3319,50 @@
LStoreKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
- Register key = ToRegister(instr->key());
+ Register key = no_reg;
ExternalArrayType array_type = instr->array_type();
+ bool key_is_constant = instr->key()->IsConstantOperand();
+ int constant_key = 0;
+ if (key_is_constant) {
+ constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+ if (constant_key & 0xF0000000) {
+ Abort("array index constant value too big.");
+ }
+ } else {
+ key = ToRegister(instr->key());
+ }
+ int shift_size = ExternalArrayTypeToShiftSize(array_type);
- if (array_type == kExternalFloatArray) {
+ if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) {
CpuFeatures::Scope scope(VFP3);
DwVfpRegister value(ToDoubleRegister(instr->value()));
- __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
- __ vcvt_f32_f64(double_scratch0().low(), value);
- __ vstr(double_scratch0().low(), scratch0(), 0);
- } else if (array_type == kExternalDoubleArray) {
- CpuFeatures::Scope scope(VFP3);
- DwVfpRegister value(ToDoubleRegister(instr->value()));
- __ add(scratch0(), external_pointer, Operand(key, LSL, 3));
- __ vstr(value, scratch0(), 0);
+ Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
+ : Operand(key, LSL, shift_size));
+ __ add(scratch0(), external_pointer, operand);
+ if (array_type == kExternalFloatArray) {
+ __ vcvt_f32_f64(double_scratch0().low(), value);
+ __ vstr(double_scratch0().low(), scratch0(), 0);
+ } else { // i.e. array_type == kExternalDoubleArray
+ __ vstr(value, scratch0(), 0);
+ }
} else {
Register value(ToRegister(instr->value()));
+ MemOperand mem_operand(key_is_constant
+ ? MemOperand(external_pointer, constant_key * (1 << shift_size))
+ : MemOperand(external_pointer, key, LSL, shift_size));
switch (array_type) {
case kExternalPixelArray:
- // Clamp the value to [0..255].
- __ Usat(value, 8, Operand(value));
- __ strb(value, MemOperand(external_pointer, key));
- break;
case kExternalByteArray:
case kExternalUnsignedByteArray:
- __ strb(value, MemOperand(external_pointer, key));
+ __ strb(value, mem_operand);
break;
case kExternalShortArray:
case kExternalUnsignedShortArray:
- __ strh(value, MemOperand(external_pointer, key, LSL, 1));
+ __ strh(value, mem_operand);
break;
case kExternalIntArray:
case kExternalUnsignedIntArray:
- __ str(value, MemOperand(external_pointer, key, LSL, 2));
+ __ str(value, mem_operand);
break;
case kExternalFloatArray:
case kExternalDoubleArray:
@@ -3867,22 +3952,41 @@
void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
Register input = ToRegister(instr->InputAt(0));
Register scratch = scratch0();
- InstanceType first = instr->hydrogen()->first();
- InstanceType last = instr->hydrogen()->last();
__ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
__ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
- __ cmp(scratch, Operand(first));
- // If there is only one type in the interval check for equality.
- if (first == last) {
- DeoptimizeIf(ne, instr->environment());
+ if (instr->hydrogen()->is_interval_check()) {
+ InstanceType first;
+ InstanceType last;
+ instr->hydrogen()->GetCheckInterval(&first, &last);
+
+ __ cmp(scratch, Operand(first));
+
+ // If there is only one type in the interval check for equality.
+ if (first == last) {
+ DeoptimizeIf(ne, instr->environment());
+ } else {
+ DeoptimizeIf(lo, instr->environment());
+ // Omit check for the last type.
+ if (last != LAST_TYPE) {
+ __ cmp(scratch, Operand(last));
+ DeoptimizeIf(hi, instr->environment());
+ }
+ }
} else {
- DeoptimizeIf(lo, instr->environment());
- // Omit check for the last type.
- if (last != LAST_TYPE) {
- __ cmp(scratch, Operand(last));
- DeoptimizeIf(hi, instr->environment());
+ uint8_t mask;
+ uint8_t tag;
+ instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
+
+ if (IsPowerOf2(mask)) {
+ ASSERT(tag == 0 || IsPowerOf2(tag));
+ __ tst(scratch, Operand(mask));
+ DeoptimizeIf(tag == 0 ? ne : eq, instr->environment());
+ } else {
+ __ and_(scratch, scratch, Operand(mask));
+ __ cmp(scratch, Operand(tag));
+ DeoptimizeIf(ne, instr->environment());
}
}
}
@@ -3907,6 +4011,59 @@
}
+void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
+ DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
+ Register result_reg = ToRegister(instr->result());
+ DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
+ __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
+}
+
+
+void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
+ Register unclamped_reg = ToRegister(instr->unclamped());
+ Register result_reg = ToRegister(instr->result());
+ __ ClampUint8(result_reg, unclamped_reg);
+}
+
+
+void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
+ Register scratch = scratch0();
+ Register input_reg = ToRegister(instr->unclamped());
+ Register result_reg = ToRegister(instr->result());
+ DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
+ Label is_smi, done, heap_number;
+
+ // Both smi and heap number cases are handled.
+ __ JumpIfSmi(input_reg, &is_smi);
+
+ // Check for heap number
+ __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
+ __ cmp(scratch, Operand(factory()->heap_number_map()));
+ __ b(eq, &heap_number);
+
+ // Check for undefined. Undefined is converted to zero for clamping
+ // conversions.
+ __ cmp(input_reg, Operand(factory()->undefined_value()));
+ DeoptimizeIf(ne, instr->environment());
+ __ movt(input_reg, 0);
+ __ jmp(&done);
+
+ // Heap number
+ __ bind(&heap_number);
+ __ vldr(double_scratch0(), FieldMemOperand(input_reg,
+ HeapNumber::kValueOffset));
+ __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg);
+ __ jmp(&done);
+
+ // smi
+ __ bind(&is_smi);
+ __ SmiUntag(result_reg, input_reg);
+ __ ClampUint8(result_reg, result_reg);
+
+ __ bind(&done);
+}
+
+
void LCodeGen::LoadHeapObject(Register result,
Handle<HeapObject> object) {
if (heap()->InNewSpace(*object)) {
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698