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

Side by Side 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 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(Runtime::Function* function, 328 void LCodeGen::CallRuntime(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 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity)); 2253 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity));
2184 __ ucomisd(xmm_scratch, input_reg); 2254 __ ucomisd(xmm_scratch, input_reg);
2185 DeoptimizeIf(equal, instr->environment()); 2255 DeoptimizeIf(equal, instr->environment());
2186 __ sqrtsd(input_reg, input_reg); 2256 __ sqrtsd(input_reg, input_reg);
2187 } 2257 }
2188 2258
2189 2259
2190 void LCodeGen::DoPower(LPower* instr) { 2260 void LCodeGen::DoPower(LPower* instr) {
2191 LOperand* left = instr->left(); 2261 LOperand* left = instr->left();
2192 LOperand* right = instr->right(); 2262 LOperand* right = instr->right();
2263 DoubleRegister result_reg = ToDoubleRegister(instr->result());
2193 Representation exponent_type = instr->hydrogen()->right()->representation(); 2264 Representation exponent_type = instr->hydrogen()->right()->representation();
2194 if (exponent_type.IsDouble()) { 2265 if (exponent_type.IsDouble()) {
2195 // Pass two doubles as arguments on the stack. 2266 // It is safe to use ebx directly since the instruction is marked
2196 __ PrepareCallCFunction(4, eax); 2267 // as a call.
2268 __ PrepareCallCFunction(4, ebx);
2197 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); 2269 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2198 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right)); 2270 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
2199 __ CallCFunction(ExternalReference::power_double_double_function(), 4); 2271 __ CallCFunction(ExternalReference::power_double_double_function(), 4);
2200 } else if (exponent_type.IsInteger32()) { 2272 } else if (exponent_type.IsInteger32()) {
2273 // It is safe to use ebx directly since the instruction is marked
2274 // as a call.
2275 ASSERT(!ToRegister(right).is(ebx));
2201 __ PrepareCallCFunction(4, ebx); 2276 __ PrepareCallCFunction(4, ebx);
2202 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); 2277 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2203 __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right)); 2278 __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right));
2204 __ CallCFunction(ExternalReference::power_double_int_function(), 4); 2279 __ CallCFunction(ExternalReference::power_double_int_function(), 4);
2205 } else { 2280 } else {
2206 ASSERT(exponent_type.IsTagged()); 2281 ASSERT(exponent_type.IsTagged());
2207 __ PrepareCallCFunction(4, ebx); 2282 CpuFeatures::Scope scope(SSE2);
2208 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2209 Register right_reg = ToRegister(right); 2283 Register right_reg = ToRegister(right);
2210 Label non_smi; 2284
2211 Label done; 2285 Label non_smi, call;
2212 __ test(right_reg, Immediate(kSmiTagMask)); 2286 __ test(right_reg, Immediate(kSmiTagMask));
2213 __ j(not_zero, &non_smi); 2287 __ j(not_zero, &non_smi);
2214 __ SmiUntag(right_reg); 2288 __ SmiUntag(right_reg);
2215 __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right)); 2289 __ cvtsi2sd(result_reg, Operand(right_reg));
2216 __ CallCFunction(ExternalReference::power_double_int_function(), 4); 2290 __ jmp(&call);
2217 __ jmp(&done);
2218 2291
2219 __ bind(&non_smi); 2292 __ bind(&non_smi);
2293 // It is safe to use ebx directly since the instruction is marked
2294 // as a call.
2295 ASSERT(!right_reg.is(ebx));
2220 __ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , ebx); 2296 __ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , ebx);
2221 DeoptimizeIf(not_equal, instr->environment()); 2297 DeoptimizeIf(not_equal, instr->environment());
2222 __ movdbl(xmm1, FieldOperand(right_reg, HeapNumber::kValueOffset)); 2298 __ movdbl(result_reg, FieldOperand(right_reg, HeapNumber::kValueOffset));
2223 __ movdbl(Operand(esp, 1 * kDoubleSize), xmm1); 2299
2300 __ bind(&call);
2301 __ PrepareCallCFunction(4, ebx);
2302 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2303 __ movdbl(Operand(esp, 1 * kDoubleSize), result_reg);
2224 __ CallCFunction(ExternalReference::power_double_double_function(), 4); 2304 __ CallCFunction(ExternalReference::power_double_double_function(), 4);
2225
2226 __ bind(&done);
2227 } 2305 }
2228 2306
2229 // Return value is in st(0) on ia32. 2307 // Return value is in st(0) on ia32.
2230 // Store it into the (fixed) result register. 2308 // Store it into the (fixed) result register.
2231 __ sub(Operand(esp), Immediate(kDoubleSize)); 2309 __ sub(Operand(esp), Immediate(kDoubleSize));
2232 __ fstp_d(Operand(esp, 0)); 2310 __ fstp_d(Operand(esp, 0));
2233 __ movdbl(ToDoubleRegister(instr->result()), Operand(esp, 0)); 2311 __ movdbl(result_reg, Operand(esp, 0));
2234 __ add(Operand(esp), Immediate(kDoubleSize)); 2312 __ add(Operand(esp), Immediate(kDoubleSize));
2235 } 2313 }
2236 2314
2237 2315
2316 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
2317 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2318 TranscendentalCacheStub stub(TranscendentalCache::LOG,
2319 TranscendentalCacheStub::UNTAGGED);
2320 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2321 }
2322
2323
2324 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
2325 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2326 TranscendentalCacheStub stub(TranscendentalCache::COS,
2327 TranscendentalCacheStub::UNTAGGED);
2328 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2329 }
2330
2331
2332 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
2333 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2334 TranscendentalCacheStub stub(TranscendentalCache::SIN,
2335 TranscendentalCacheStub::UNTAGGED);
2336 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2337 }
2338
2339
2238 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { 2340 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
2239 switch (instr->op()) { 2341 switch (instr->op()) {
2240 case kMathAbs: 2342 case kMathAbs:
2241 DoMathAbs(instr); 2343 DoMathAbs(instr);
2242 break; 2344 break;
2243 case kMathFloor: 2345 case kMathFloor:
2244 DoMathFloor(instr); 2346 DoMathFloor(instr);
2245 break; 2347 break;
2246 case kMathRound: 2348 case kMathRound:
2247 DoMathRound(instr); 2349 DoMathRound(instr);
2248 break; 2350 break;
2249 case kMathSqrt: 2351 case kMathSqrt:
2250 DoMathSqrt(instr); 2352 DoMathSqrt(instr);
2251 break; 2353 break;
2252 case kMathPowHalf: 2354 case kMathPowHalf:
2253 DoMathPowHalf(instr); 2355 DoMathPowHalf(instr);
2254 break; 2356 break;
2357 case kMathCos:
2358 DoMathCos(instr);
2359 break;
2360 case kMathSin:
2361 DoMathSin(instr);
2362 break;
2363 case kMathLog:
2364 DoMathLog(instr);
2365 break;
2366
2255 default: 2367 default:
2256 UNREACHABLE(); 2368 UNREACHABLE();
2257 } 2369 }
2258 } 2370 }
2259 2371
2260 2372
2261 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 2373 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
2262 ASSERT(ToRegister(instr->result()).is(eax)); 2374 ASSERT(ToRegister(instr->result()).is(eax));
2263 2375
2264 int arity = instr->arity(); 2376 int arity = instr->arity();
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after
3161 ASSERT(!environment->HasBeenRegistered()); 3273 ASSERT(!environment->HasBeenRegistered());
3162 RegisterEnvironmentForDeoptimization(environment); 3274 RegisterEnvironmentForDeoptimization(environment);
3163 ASSERT(osr_pc_offset_ == -1); 3275 ASSERT(osr_pc_offset_ == -1);
3164 osr_pc_offset_ = masm()->pc_offset(); 3276 osr_pc_offset_ = masm()->pc_offset();
3165 } 3277 }
3166 3278
3167 3279
3168 #undef __ 3280 #undef __
3169 3281
3170 } } // namespace v8::internal 3282 } } // 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