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

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

Issue 6062002: Merge 6006:6095 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 10 years 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 6095)
+++ src/ia32/lithium-codegen-ia32.cc (working copy)
@@ -315,6 +315,13 @@
__ call(code, mode);
RecordSafepoint(&no_pointers, Safepoint::kNoDeoptimizationIndex);
}
+
+ // Signal that we don't inline smi code before these stubs in the
+ // optimizing code generator.
+ if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC ||
+ code->kind() == Code::COMPARE_IC) {
+ __ nop();
+ }
}
@@ -679,7 +686,8 @@
break;
}
case CodeStub::TranscendentalCache: {
- TranscendentalCacheStub stub(instr->transcendental_type());
+ TranscendentalCacheStub stub(instr->transcendental_type(),
+ TranscendentalCacheStub::TAGGED);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
@@ -1403,6 +1411,71 @@
}
+Condition LCodeGen::EmitIsObject(Register input,
+ Register temp1,
+ Register temp2,
+ Label* is_not_object,
+ Label* is_object) {
+ ASSERT(!input.is(temp1));
+ ASSERT(!input.is(temp2));
+ ASSERT(!temp1.is(temp2));
+
+ __ test(input, Immediate(kSmiTagMask));
+ __ j(equal, is_not_object);
+
+ __ cmp(input, Factory::null_value());
+ __ j(equal, is_object);
+
+ __ mov(temp1, FieldOperand(input, HeapObject::kMapOffset));
+ // Undetectable objects behave like undefined.
+ __ movzx_b(temp2, FieldOperand(temp1, Map::kBitFieldOffset));
+ __ test(temp2, Immediate(1 << Map::kIsUndetectable));
+ __ j(not_zero, is_not_object);
+
+ __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset));
+ __ cmp(temp2, FIRST_JS_OBJECT_TYPE);
+ __ j(below, is_not_object);
+ __ cmp(temp2, LAST_JS_OBJECT_TYPE);
+ return below_equal;
+}
+
+
+void LCodeGen::DoIsObject(LIsObject* instr) {
+ Register reg = ToRegister(instr->input());
+ Register result = ToRegister(instr->result());
+ Register temp = ToRegister(instr->temp());
+ Label is_false, is_true, done;
+
+ Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
+ __ j(true_cond, &is_true);
+
+ __ bind(&is_false);
+ __ mov(result, Handle<Object>(Heap::false_value()));
+ __ jmp(&done);
+
+ __ bind(&is_true);
+ __ mov(result, Handle<Object>(Heap::true_value()));
+
+ __ bind(&done);
+}
+
+
+void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
+ Register reg = ToRegister(instr->input());
+ Register temp = ToRegister(instr->temp());
+ Register temp2 = ToRegister(instr->temp2());
+
+ int true_block = chunk_->LookupDestination(instr->true_block_id());
+ int false_block = chunk_->LookupDestination(instr->false_block_id());
+ Label* true_label = chunk_->GetAssemblyLabel(true_block);
+ Label* false_label = chunk_->GetAssemblyLabel(false_block);
+
+ Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label);
+
+ EmitBranch(true_block, false_block, true_cond);
+}
+
+
void LCodeGen::DoIsSmi(LIsSmi* instr) {
Operand input = ToOperand(instr->input());
Register result = ToRegister(instr->result());
@@ -1627,9 +1700,8 @@
void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
- InstanceofStub stub;
- __ push(ToOperand(instr->left()));
- __ push(ToOperand(instr->right()));
+ // Object and function are in fixed registers eax and edx.
+ InstanceofStub stub(InstanceofStub::kArgsInRegisters);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
NearLabel true_value, done;
@@ -1647,9 +1719,7 @@
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
- InstanceofStub stub;
- __ push(ToOperand(instr->left()));
- __ push(ToOperand(instr->right()));
+ InstanceofStub stub(InstanceofStub::kArgsInRegisters);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
__ test(eax, Operand(eax));
EmitBranch(true_block, false_block, zero);
@@ -2190,51 +2260,83 @@
void LCodeGen::DoPower(LPower* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
+ DoubleRegister result_reg = ToDoubleRegister(instr->result());
Representation exponent_type = instr->hydrogen()->right()->representation();
if (exponent_type.IsDouble()) {
- // Pass two doubles as arguments on the stack.
- __ PrepareCallCFunction(4, eax);
+ // It is safe to use ebx directly since the instruction is marked
+ // as a call.
+ __ PrepareCallCFunction(4, ebx);
__ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
__ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
__ CallCFunction(ExternalReference::power_double_double_function(), 4);
} else if (exponent_type.IsInteger32()) {
+ // It is safe to use ebx directly since the instruction is marked
+ // as a call.
+ ASSERT(!ToRegister(right).is(ebx));
__ PrepareCallCFunction(4, ebx);
__ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
__ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right));
__ CallCFunction(ExternalReference::power_double_int_function(), 4);
} else {
ASSERT(exponent_type.IsTagged());
- __ PrepareCallCFunction(4, ebx);
- __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
+ CpuFeatures::Scope scope(SSE2);
Register right_reg = ToRegister(right);
- Label non_smi;
- Label done;
+
+ Label non_smi, call;
__ test(right_reg, Immediate(kSmiTagMask));
__ j(not_zero, &non_smi);
__ SmiUntag(right_reg);
- __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right));
- __ CallCFunction(ExternalReference::power_double_int_function(), 4);
- __ jmp(&done);
+ __ cvtsi2sd(result_reg, Operand(right_reg));
+ __ jmp(&call);
__ bind(&non_smi);
+ // It is safe to use ebx directly since the instruction is marked
+ // as a call.
+ ASSERT(!right_reg.is(ebx));
__ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , ebx);
DeoptimizeIf(not_equal, instr->environment());
- __ movdbl(xmm1, FieldOperand(right_reg, HeapNumber::kValueOffset));
- __ movdbl(Operand(esp, 1 * kDoubleSize), xmm1);
+ __ movdbl(result_reg, FieldOperand(right_reg, HeapNumber::kValueOffset));
+
+ __ bind(&call);
+ __ PrepareCallCFunction(4, ebx);
+ __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
+ __ movdbl(Operand(esp, 1 * kDoubleSize), result_reg);
__ CallCFunction(ExternalReference::power_double_double_function(), 4);
-
- __ bind(&done);
}
// Return value is in st(0) on ia32.
// Store it into the (fixed) result register.
__ sub(Operand(esp), Immediate(kDoubleSize));
__ fstp_d(Operand(esp, 0));
- __ movdbl(ToDoubleRegister(instr->result()), Operand(esp, 0));
+ __ movdbl(result_reg, Operand(esp, 0));
__ add(Operand(esp), Immediate(kDoubleSize));
}
+void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+ TranscendentalCacheStub stub(TranscendentalCache::LOG,
+ TranscendentalCacheStub::UNTAGGED);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+ TranscendentalCacheStub stub(TranscendentalCache::COS,
+ TranscendentalCacheStub::UNTAGGED);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+ TranscendentalCacheStub stub(TranscendentalCache::SIN,
+ TranscendentalCacheStub::UNTAGGED);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
switch (instr->op()) {
case kMathAbs:
@@ -2252,6 +2354,16 @@
case kMathPowHalf:
DoMathPowHalf(instr);
break;
+ case kMathCos:
+ DoMathCos(instr);
+ break;
+ case kMathSin:
+ DoMathSin(instr);
+ break;
+ case kMathLog:
+ DoMathLog(instr);
+ break;
+
default:
UNREACHABLE();
}
« 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