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

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 6580038: [Isolates] Merge from bleeding_edge, revisions 5934-6100. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 LPointerMap* pointers = instr->pointer_map(); 308 LPointerMap* pointers = instr->pointer_map();
309 RecordPosition(pointers->position()); 309 RecordPosition(pointers->position());
310 __ call(code, mode); 310 __ call(code, mode);
311 RegisterLazyDeoptimization(instr); 311 RegisterLazyDeoptimization(instr);
312 } else { 312 } else {
313 LPointerMap no_pointers(0); 313 LPointerMap no_pointers(0);
314 RecordPosition(no_pointers.position()); 314 RecordPosition(no_pointers.position());
315 __ call(code, mode); 315 __ call(code, mode);
316 RecordSafepoint(&no_pointers, Safepoint::kNoDeoptimizationIndex); 316 RecordSafepoint(&no_pointers, Safepoint::kNoDeoptimizationIndex);
317 } 317 }
318
319 // Signal that we don't inline smi code before these stubs in the
320 // optimizing code generator.
321 if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC ||
322 code->kind() == Code::COMPARE_IC) {
323 __ nop();
324 }
318 } 325 }
319 326
320 327
321 void LCodeGen::CallRuntime(const Runtime::Function* function, 328 void LCodeGen::CallRuntime(const Runtime::Function* function,
322 int num_arguments, 329 int num_arguments,
323 LInstruction* instr) { 330 LInstruction* instr) {
324 ASSERT(instr != NULL); 331 ASSERT(instr != NULL);
325 LPointerMap* pointers = instr->pointer_map(); 332 LPointerMap* pointers = instr->pointer_map();
326 ASSERT(pointers != NULL); 333 ASSERT(pointers != NULL);
327 RecordPosition(pointers->position()); 334 RecordPosition(pointers->position());
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 StringAddStub stub(NO_STRING_ADD_FLAGS); 679 StringAddStub stub(NO_STRING_ADD_FLAGS);
673 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 680 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
674 break; 681 break;
675 } 682 }
676 case CodeStub::StringCompare: { 683 case CodeStub::StringCompare: {
677 StringCompareStub stub; 684 StringCompareStub stub;
678 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 685 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
679 break; 686 break;
680 } 687 }
681 case CodeStub::TranscendentalCache: { 688 case CodeStub::TranscendentalCache: {
682 TranscendentalCacheStub stub(instr->transcendental_type()); 689 TranscendentalCacheStub stub(instr->transcendental_type(),
690 TranscendentalCacheStub::TAGGED);
683 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 691 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
684 break; 692 break;
685 } 693 }
686 default: 694 default:
687 UNREACHABLE(); 695 UNREACHABLE();
688 } 696 }
689 } 697 }
690 698
691 699
692 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 700 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 // the map. The object has already been smi checked. 1404 // the map. The object has already been smi checked.
1397 Register scratch = ToRegister(instr->temp()); 1405 Register scratch = ToRegister(instr->temp());
1398 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1406 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1399 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); 1407 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
1400 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); 1408 __ test(scratch, Immediate(1 << Map::kIsUndetectable));
1401 EmitBranch(true_block, false_block, not_zero); 1409 EmitBranch(true_block, false_block, not_zero);
1402 } 1410 }
1403 } 1411 }
1404 1412
1405 1413
1414 Condition LCodeGen::EmitIsObject(Register input,
1415 Register temp1,
1416 Register temp2,
1417 Label* is_not_object,
1418 Label* is_object) {
1419 ASSERT(!input.is(temp1));
1420 ASSERT(!input.is(temp2));
1421 ASSERT(!temp1.is(temp2));
1422
1423 __ test(input, Immediate(kSmiTagMask));
1424 __ j(equal, is_not_object);
1425
1426 __ cmp(input, FACTORY->null_value());
1427 __ j(equal, is_object);
1428
1429 __ mov(temp1, FieldOperand(input, HeapObject::kMapOffset));
1430 // Undetectable objects behave like undefined.
1431 __ movzx_b(temp2, FieldOperand(temp1, Map::kBitFieldOffset));
1432 __ test(temp2, Immediate(1 << Map::kIsUndetectable));
1433 __ j(not_zero, is_not_object);
1434
1435 __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset));
1436 __ cmp(temp2, FIRST_JS_OBJECT_TYPE);
1437 __ j(below, is_not_object);
1438 __ cmp(temp2, LAST_JS_OBJECT_TYPE);
1439 return below_equal;
1440 }
1441
1442
1443 void LCodeGen::DoIsObject(LIsObject* instr) {
1444 Register reg = ToRegister(instr->input());
1445 Register result = ToRegister(instr->result());
1446 Register temp = ToRegister(instr->temp());
1447 Label is_false, is_true, done;
1448
1449 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
1450 __ j(true_cond, &is_true);
1451
1452 __ bind(&is_false);
1453 __ mov(result, Handle<Object>(HEAP->false_value()));
1454 __ jmp(&done);
1455
1456 __ bind(&is_true);
1457 __ mov(result, Handle<Object>(HEAP->true_value()));
1458
1459 __ bind(&done);
1460 }
1461
1462
1463 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1464 Register reg = ToRegister(instr->input());
1465 Register temp = ToRegister(instr->temp());
1466 Register temp2 = ToRegister(instr->temp2());
1467
1468 int true_block = chunk_->LookupDestination(instr->true_block_id());
1469 int false_block = chunk_->LookupDestination(instr->false_block_id());
1470 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1471 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1472
1473 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label);
1474
1475 EmitBranch(true_block, false_block, true_cond);
1476 }
1477
1478
1406 void LCodeGen::DoIsSmi(LIsSmi* instr) { 1479 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1407 Operand input = ToOperand(instr->input()); 1480 Operand input = ToOperand(instr->input());
1408 Register result = ToRegister(instr->result()); 1481 Register result = ToRegister(instr->result());
1409 1482
1410 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1483 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1411 __ test(input, Immediate(kSmiTagMask)); 1484 __ test(input, Immediate(kSmiTagMask));
1412 __ mov(result, Handle<Object>(HEAP->true_value())); 1485 __ mov(result, Handle<Object>(HEAP->true_value()));
1413 NearLabel done; 1486 NearLabel done;
1414 __ j(zero, &done); 1487 __ j(zero, &done);
1415 __ mov(result, Handle<Object>(HEAP->false_value())); 1488 __ mov(result, Handle<Object>(HEAP->false_value()));
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 Register reg = ToRegister(instr->input()); 1693 Register reg = ToRegister(instr->input());
1621 int true_block = instr->true_block_id(); 1694 int true_block = instr->true_block_id();
1622 int false_block = instr->false_block_id(); 1695 int false_block = instr->false_block_id();
1623 1696
1624 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 1697 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
1625 EmitBranch(true_block, false_block, equal); 1698 EmitBranch(true_block, false_block, equal);
1626 } 1699 }
1627 1700
1628 1701
1629 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1702 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1630 InstanceofStub stub; 1703 // Object and function are in fixed registers eax and edx.
1631 __ push(ToOperand(instr->left())); 1704 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
1632 __ push(ToOperand(instr->right()));
1633 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1705 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1634 1706
1635 NearLabel true_value, done; 1707 NearLabel true_value, done;
1636 __ test(eax, Operand(eax)); 1708 __ test(eax, Operand(eax));
1637 __ j(zero, &true_value); 1709 __ j(zero, &true_value);
1638 __ mov(ToRegister(instr->result()), FACTORY->false_value()); 1710 __ mov(ToRegister(instr->result()), FACTORY->false_value());
1639 __ jmp(&done); 1711 __ jmp(&done);
1640 __ bind(&true_value); 1712 __ bind(&true_value);
1641 __ mov(ToRegister(instr->result()), FACTORY->true_value()); 1713 __ mov(ToRegister(instr->result()), FACTORY->true_value());
1642 __ bind(&done); 1714 __ bind(&done);
1643 } 1715 }
1644 1716
1645 1717
1646 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { 1718 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) {
1647 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1719 int true_block = chunk_->LookupDestination(instr->true_block_id());
1648 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1720 int false_block = chunk_->LookupDestination(instr->false_block_id());
1649 1721
1650 InstanceofStub stub; 1722 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
1651 __ push(ToOperand(instr->left()));
1652 __ push(ToOperand(instr->right()));
1653 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1723 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1654 __ test(eax, Operand(eax)); 1724 __ test(eax, Operand(eax));
1655 EmitBranch(true_block, false_block, zero); 1725 EmitBranch(true_block, false_block, zero);
1656 } 1726 }
1657 1727
1658 1728
1659 static Condition ComputeCompareCondition(Token::Value op) { 1729 static Condition ComputeCompareCondition(Token::Value op) {
1660 switch (op) { 1730 switch (op) {
1661 case Token::EQ_STRICT: 1731 case Token::EQ_STRICT:
1662 case Token::EQ: 1732 case Token::EQ:
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
2169 } 2239 }
2170 2240
2171 2241
2172 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 2242 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
2173 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2243 XMMRegister input_reg = ToDoubleRegister(instr->input());
2174 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2244 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2175 __ sqrtsd(input_reg, input_reg); 2245 __ sqrtsd(input_reg, input_reg);
2176 } 2246 }
2177 2247
2178 2248
2249 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
2250 XMMRegister xmm_scratch = xmm0;
2251 XMMRegister input_reg = ToDoubleRegister(instr->input());
2252 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2253 ExternalReference negative_infinity =
2254 ExternalReference::address_of_negative_infinity();
2255 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity));
2256 __ ucomisd(xmm_scratch, input_reg);
2257 DeoptimizeIf(equal, instr->environment());
2258 __ sqrtsd(input_reg, input_reg);
2259 }
2260
2261
2262 void LCodeGen::DoPower(LPower* instr) {
2263 LOperand* left = instr->left();
2264 LOperand* right = instr->right();
2265 DoubleRegister result_reg = ToDoubleRegister(instr->result());
2266 Representation exponent_type = instr->hydrogen()->right()->representation();
2267 if (exponent_type.IsDouble()) {
2268 // It is safe to use ebx directly since the instruction is marked
2269 // as a call.
2270 __ PrepareCallCFunction(4, ebx);
2271 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2272 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
2273 __ CallCFunction(ExternalReference::power_double_double_function(), 4);
2274 } else if (exponent_type.IsInteger32()) {
2275 // It is safe to use ebx directly since the instruction is marked
2276 // as a call.
2277 ASSERT(!ToRegister(right).is(ebx));
2278 __ PrepareCallCFunction(4, ebx);
2279 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2280 __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right));
2281 __ CallCFunction(ExternalReference::power_double_int_function(), 4);
2282 } else {
2283 ASSERT(exponent_type.IsTagged());
2284 CpuFeatures::Scope scope(SSE2);
2285 Register right_reg = ToRegister(right);
2286
2287 Label non_smi, call;
2288 __ test(right_reg, Immediate(kSmiTagMask));
2289 __ j(not_zero, &non_smi);
2290 __ SmiUntag(right_reg);
2291 __ cvtsi2sd(result_reg, Operand(right_reg));
2292 __ jmp(&call);
2293
2294 __ bind(&non_smi);
2295 // It is safe to use ebx directly since the instruction is marked
2296 // as a call.
2297 ASSERT(!right_reg.is(ebx));
2298 __ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , ebx);
2299 DeoptimizeIf(not_equal, instr->environment());
2300 __ movdbl(result_reg, FieldOperand(right_reg, HeapNumber::kValueOffset));
2301
2302 __ bind(&call);
2303 __ PrepareCallCFunction(4, ebx);
2304 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2305 __ movdbl(Operand(esp, 1 * kDoubleSize), result_reg);
2306 __ CallCFunction(ExternalReference::power_double_double_function(), 4);
2307 }
2308
2309 // Return value is in st(0) on ia32.
2310 // Store it into the (fixed) result register.
2311 __ sub(Operand(esp), Immediate(kDoubleSize));
2312 __ fstp_d(Operand(esp, 0));
2313 __ movdbl(result_reg, Operand(esp, 0));
2314 __ add(Operand(esp), Immediate(kDoubleSize));
2315 }
2316
2317
2318 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
2319 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2320 TranscendentalCacheStub stub(TranscendentalCache::LOG,
2321 TranscendentalCacheStub::UNTAGGED);
2322 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2323 }
2324
2325
2326 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
2327 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2328 TranscendentalCacheStub stub(TranscendentalCache::COS,
2329 TranscendentalCacheStub::UNTAGGED);
2330 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2331 }
2332
2333
2334 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
2335 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2336 TranscendentalCacheStub stub(TranscendentalCache::SIN,
2337 TranscendentalCacheStub::UNTAGGED);
2338 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2339 }
2340
2341
2179 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { 2342 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
2180 switch (instr->op()) { 2343 switch (instr->op()) {
2181 case kMathAbs: 2344 case kMathAbs:
2182 DoMathAbs(instr); 2345 DoMathAbs(instr);
2183 break; 2346 break;
2184 case kMathFloor: 2347 case kMathFloor:
2185 DoMathFloor(instr); 2348 DoMathFloor(instr);
2186 break; 2349 break;
2187 case kMathRound: 2350 case kMathRound:
2188 DoMathRound(instr); 2351 DoMathRound(instr);
2189 break; 2352 break;
2190 case kMathSqrt: 2353 case kMathSqrt:
2191 DoMathSqrt(instr); 2354 DoMathSqrt(instr);
2192 break; 2355 break;
2356 case kMathPowHalf:
2357 DoMathPowHalf(instr);
2358 break;
2359 case kMathCos:
2360 DoMathCos(instr);
2361 break;
2362 case kMathSin:
2363 DoMathSin(instr);
2364 break;
2365 case kMathLog:
2366 DoMathLog(instr);
2367 break;
2368
2193 default: 2369 default:
2194 UNREACHABLE(); 2370 UNREACHABLE();
2195 } 2371 }
2196 } 2372 }
2197 2373
2198 2374
2199 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 2375 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
2200 ASSERT(ToRegister(instr->result()).is(eax)); 2376 ASSERT(ToRegister(instr->result()).is(eax));
2201 2377
2202 int arity = instr->arity(); 2378 int arity = instr->arity();
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after
3099 ASSERT(!environment->HasBeenRegistered()); 3275 ASSERT(!environment->HasBeenRegistered());
3100 RegisterEnvironmentForDeoptimization(environment); 3276 RegisterEnvironmentForDeoptimization(environment);
3101 ASSERT(osr_pc_offset_ == -1); 3277 ASSERT(osr_pc_offset_ == -1);
3102 osr_pc_offset_ = masm()->pc_offset(); 3278 osr_pc_offset_ = masm()->pc_offset();
3103 } 3279 }
3104 3280
3105 3281
3106 #undef __ 3282 #undef __
3107 3283
3108 } } // namespace v8::internal 3284 } } // namespace v8::internal
OLDNEW
« 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