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

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

Issue 2078022: Complete the full codegenerator on x64. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/flag-definitions.h ('k') | src/ia32/full-codegen-ia32.cc » ('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 6145 matching lines...) Expand 10 before | Expand all | Expand 10 after
6156 Result map = allocator()->Allocate(); 6156 Result map = allocator()->Allocate();
6157 ASSERT(map.is_valid()); 6157 ASSERT(map.is_valid());
6158 __ mov(map.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset)); 6158 __ mov(map.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
6159 // Undetectable objects behave like undefined when tested with typeof. 6159 // Undetectable objects behave like undefined when tested with typeof.
6160 __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kBitFieldOffset)); 6160 __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kBitFieldOffset));
6161 __ test(map.reg(), Immediate(1 << Map::kIsUndetectable)); 6161 __ test(map.reg(), Immediate(1 << Map::kIsUndetectable));
6162 destination()->false_target()->Branch(not_zero); 6162 destination()->false_target()->Branch(not_zero);
6163 __ mov(map.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset)); 6163 __ mov(map.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
6164 __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kInstanceTypeOffset)); 6164 __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kInstanceTypeOffset));
6165 __ cmp(map.reg(), FIRST_JS_OBJECT_TYPE); 6165 __ cmp(map.reg(), FIRST_JS_OBJECT_TYPE);
6166 destination()->false_target()->Branch(less); 6166 destination()->false_target()->Branch(below);
6167 __ cmp(map.reg(), LAST_JS_OBJECT_TYPE); 6167 __ cmp(map.reg(), LAST_JS_OBJECT_TYPE);
6168 obj.Unuse(); 6168 obj.Unuse();
6169 map.Unuse(); 6169 map.Unuse();
6170 destination()->Split(less_equal); 6170 destination()->Split(below_equal);
6171 } 6171 }
6172 6172
6173 6173
6174 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) { 6174 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
6175 // This generates a fast version of: 6175 // This generates a fast version of:
6176 // (%_ClassOf(arg) === 'Function') 6176 // (%_ClassOf(arg) === 'Function')
6177 ASSERT(args->length() == 1); 6177 ASSERT(args->length() == 1);
6178 Load(args->at(0)); 6178 Load(args->at(0));
6179 Result obj = frame_->Pop(); 6179 Result obj = frame_->Pop();
6180 obj.ToRegister(); 6180 obj.ToRegister();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
6273 // If the object is a smi, we return null. 6273 // If the object is a smi, we return null.
6274 __ test(obj.reg(), Immediate(kSmiTagMask)); 6274 __ test(obj.reg(), Immediate(kSmiTagMask));
6275 null.Branch(zero); 6275 null.Branch(zero);
6276 6276
6277 // Check that the object is a JS object but take special care of JS 6277 // Check that the object is a JS object but take special care of JS
6278 // functions to make sure they have 'Function' as their class. 6278 // functions to make sure they have 'Function' as their class.
6279 { Result tmp = allocator()->Allocate(); 6279 { Result tmp = allocator()->Allocate();
6280 __ mov(obj.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset)); 6280 __ mov(obj.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
6281 __ movzx_b(tmp.reg(), FieldOperand(obj.reg(), Map::kInstanceTypeOffset)); 6281 __ movzx_b(tmp.reg(), FieldOperand(obj.reg(), Map::kInstanceTypeOffset));
6282 __ cmp(tmp.reg(), FIRST_JS_OBJECT_TYPE); 6282 __ cmp(tmp.reg(), FIRST_JS_OBJECT_TYPE);
6283 null.Branch(less); 6283 null.Branch(below);
6284 6284
6285 // As long as JS_FUNCTION_TYPE is the last instance type and it is 6285 // As long as JS_FUNCTION_TYPE is the last instance type and it is
6286 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for 6286 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
6287 // LAST_JS_OBJECT_TYPE. 6287 // LAST_JS_OBJECT_TYPE.
6288 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 6288 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
6289 ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); 6289 ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
6290 __ cmp(tmp.reg(), JS_FUNCTION_TYPE); 6290 __ cmp(tmp.reg(), JS_FUNCTION_TYPE);
6291 function.Branch(equal); 6291 function.Branch(equal);
6292 } 6292 }
6293 6293
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
6862 frame_->Spill(index2.reg()); 6862 frame_->Spill(index2.reg());
6863 6863
6864 DeferredSwapElements* deferred = new DeferredSwapElements(object.reg(), 6864 DeferredSwapElements* deferred = new DeferredSwapElements(object.reg(),
6865 index1.reg(), 6865 index1.reg(),
6866 index2.reg()); 6866 index2.reg());
6867 6867
6868 // Fetch the map and check if array is in fast case. 6868 // Fetch the map and check if array is in fast case.
6869 // Check that object doesn't require security checks and 6869 // Check that object doesn't require security checks and
6870 // has no indexed interceptor. 6870 // has no indexed interceptor.
6871 __ CmpObjectType(object.reg(), FIRST_JS_OBJECT_TYPE, tmp1.reg()); 6871 __ CmpObjectType(object.reg(), FIRST_JS_OBJECT_TYPE, tmp1.reg());
6872 deferred->Branch(less); 6872 deferred->Branch(below);
6873 __ movzx_b(tmp1.reg(), FieldOperand(tmp1.reg(), Map::kBitFieldOffset)); 6873 __ movzx_b(tmp1.reg(), FieldOperand(tmp1.reg(), Map::kBitFieldOffset));
6874 __ test(tmp1.reg(), Immediate(KeyedLoadIC::kSlowCaseBitFieldMask)); 6874 __ test(tmp1.reg(), Immediate(KeyedLoadIC::kSlowCaseBitFieldMask));
6875 deferred->Branch(not_zero); 6875 deferred->Branch(not_zero);
6876 6876
6877 // Check the object's elements are in fast case. 6877 // Check the object's elements are in fast case.
6878 __ mov(tmp1.reg(), FieldOperand(object.reg(), JSObject::kElementsOffset)); 6878 __ mov(tmp1.reg(), FieldOperand(object.reg(), JSObject::kElementsOffset));
6879 __ cmp(FieldOperand(tmp1.reg(), HeapObject::kMapOffset), 6879 __ cmp(FieldOperand(tmp1.reg(), HeapObject::kMapOffset),
6880 Immediate(Factory::fixed_array_map())); 6880 Immediate(Factory::fixed_array_map()));
6881 deferred->Branch(not_equal); 6881 deferred->Branch(not_equal);
6882 6882
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after
8178 __ CmpObjectType(answer.reg(), JS_REGEXP_TYPE, map.reg()); 8178 __ CmpObjectType(answer.reg(), JS_REGEXP_TYPE, map.reg());
8179 destination()->false_target()->Branch(equal); 8179 destination()->false_target()->Branch(equal);
8180 8180
8181 // It can be an undetectable object. 8181 // It can be an undetectable object.
8182 __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kBitFieldOffset)); 8182 __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kBitFieldOffset));
8183 __ test(map.reg(), Immediate(1 << Map::kIsUndetectable)); 8183 __ test(map.reg(), Immediate(1 << Map::kIsUndetectable));
8184 destination()->false_target()->Branch(not_zero); 8184 destination()->false_target()->Branch(not_zero);
8185 __ mov(map.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset)); 8185 __ mov(map.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
8186 __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kInstanceTypeOffset)); 8186 __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kInstanceTypeOffset));
8187 __ cmp(map.reg(), FIRST_JS_OBJECT_TYPE); 8187 __ cmp(map.reg(), FIRST_JS_OBJECT_TYPE);
8188 destination()->false_target()->Branch(less); 8188 destination()->false_target()->Branch(below);
8189 __ cmp(map.reg(), LAST_JS_OBJECT_TYPE); 8189 __ cmp(map.reg(), LAST_JS_OBJECT_TYPE);
8190 answer.Unuse(); 8190 answer.Unuse();
8191 map.Unuse(); 8191 map.Unuse();
8192 destination()->Split(less_equal); 8192 destination()->Split(below_equal);
8193 } else { 8193 } else {
8194 // Uncommon case: typeof testing against a string literal that is 8194 // Uncommon case: typeof testing against a string literal that is
8195 // never returned from the typeof operator. 8195 // never returned from the typeof operator.
8196 answer.Unuse(); 8196 answer.Unuse();
8197 destination()->Goto(false); 8197 destination()->Goto(false);
8198 } 8198 }
8199 return; 8199 return;
8200 } else if (op == Token::LT && 8200 } else if (op == Token::LT &&
8201 right->AsLiteral() != NULL && 8201 right->AsLiteral() != NULL &&
8202 right->AsLiteral()->handle()->IsHeapNumber()) { 8202 right->AsLiteral()->handle()->IsHeapNumber()) {
(...skipping 3376 matching lines...) Expand 10 before | Expand all | Expand 10 after
11579 // There is no test for undetectability in strict equality. 11579 // There is no test for undetectability in strict equality.
11580 11580
11581 // Get the type of the first operand. 11581 // Get the type of the first operand.
11582 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 11582 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
11583 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 11583 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
11584 11584
11585 // If the first object is a JS object, we have done pointer comparison. 11585 // If the first object is a JS object, we have done pointer comparison.
11586 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 11586 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
11587 Label first_non_object; 11587 Label first_non_object;
11588 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 11588 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
11589 __ j(less, &first_non_object); 11589 __ j(below, &first_non_object);
11590 11590
11591 // Return non-zero (eax is not zero) 11591 // Return non-zero (eax is not zero)
11592 Label return_not_equal; 11592 Label return_not_equal;
11593 ASSERT(kHeapObjectTag != 0); 11593 ASSERT(kHeapObjectTag != 0);
11594 __ bind(&return_not_equal); 11594 __ bind(&return_not_equal);
11595 __ ret(0); 11595 __ ret(0);
11596 11596
11597 __ bind(&first_non_object); 11597 __ bind(&first_non_object);
11598 // Check for oddballs: true, false, null, undefined. 11598 // Check for oddballs: true, false, null, undefined.
11599 __ cmp(ecx, ODDBALL_TYPE); 11599 __ cmp(ecx, ODDBALL_TYPE);
11600 __ j(equal, &return_not_equal); 11600 __ j(equal, &return_not_equal);
11601 11601
11602 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 11602 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
11603 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 11603 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
11604 11604
11605 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 11605 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
11606 __ j(greater_equal, &return_not_equal); 11606 __ j(above_equal, &return_not_equal);
11607 11607
11608 // Check for oddballs: true, false, null, undefined. 11608 // Check for oddballs: true, false, null, undefined.
11609 __ cmp(ecx, ODDBALL_TYPE); 11609 __ cmp(ecx, ODDBALL_TYPE);
11610 __ j(equal, &return_not_equal); 11610 __ j(equal, &return_not_equal);
11611 11611
11612 // Fall through to the general case. 11612 // Fall through to the general case.
11613 } 11613 }
11614 __ bind(&slow); 11614 __ bind(&slow);
11615 } 11615 }
11616 11616
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
12244 // Get the object - go slow case if it's a smi. 12244 // Get the object - go slow case if it's a smi.
12245 Label slow; 12245 Label slow;
12246 __ mov(eax, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, function 12246 __ mov(eax, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, function
12247 __ test(eax, Immediate(kSmiTagMask)); 12247 __ test(eax, Immediate(kSmiTagMask));
12248 __ j(zero, &slow, not_taken); 12248 __ j(zero, &slow, not_taken);
12249 12249
12250 // Check that the left hand is a JS object. 12250 // Check that the left hand is a JS object.
12251 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); // eax - object map 12251 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); // eax - object map
12252 __ movzx_b(ecx, FieldOperand(eax, Map::kInstanceTypeOffset)); // ecx - type 12252 __ movzx_b(ecx, FieldOperand(eax, Map::kInstanceTypeOffset)); // ecx - type
12253 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 12253 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
12254 __ j(less, &slow, not_taken); 12254 __ j(below, &slow, not_taken);
12255 __ cmp(ecx, LAST_JS_OBJECT_TYPE); 12255 __ cmp(ecx, LAST_JS_OBJECT_TYPE);
12256 __ j(greater, &slow, not_taken); 12256 __ j(above, &slow, not_taken);
12257 12257
12258 // Get the prototype of the function. 12258 // Get the prototype of the function.
12259 __ mov(edx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address 12259 __ mov(edx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
12260 // edx is function, eax is map. 12260 // edx is function, eax is map.
12261 12261
12262 // Look up the function and the map in the instanceof cache. 12262 // Look up the function and the map in the instanceof cache.
12263 Label miss; 12263 Label miss;
12264 ExternalReference roots_address = ExternalReference::roots_address(); 12264 ExternalReference roots_address = ExternalReference::roots_address();
12265 __ mov(ecx, Immediate(Heap::kInstanceofCacheFunctionRootIndex)); 12265 __ mov(ecx, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
12266 __ cmp(edx, Operand::StaticArray(ecx, times_pointer_size, roots_address)); 12266 __ cmp(edx, Operand::StaticArray(ecx, times_pointer_size, roots_address));
12267 __ j(not_equal, &miss); 12267 __ j(not_equal, &miss);
12268 __ mov(ecx, Immediate(Heap::kInstanceofCacheMapRootIndex)); 12268 __ mov(ecx, Immediate(Heap::kInstanceofCacheMapRootIndex));
12269 __ cmp(eax, Operand::StaticArray(ecx, times_pointer_size, roots_address)); 12269 __ cmp(eax, Operand::StaticArray(ecx, times_pointer_size, roots_address));
12270 __ j(not_equal, &miss); 12270 __ j(not_equal, &miss);
12271 __ mov(ecx, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 12271 __ mov(ecx, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
12272 __ mov(eax, Operand::StaticArray(ecx, times_pointer_size, roots_address)); 12272 __ mov(eax, Operand::StaticArray(ecx, times_pointer_size, roots_address));
12273 __ ret(2 * kPointerSize); 12273 __ ret(2 * kPointerSize);
12274 12274
12275 __ bind(&miss); 12275 __ bind(&miss);
12276 __ TryGetFunctionPrototype(edx, ebx, ecx, &slow); 12276 __ TryGetFunctionPrototype(edx, ebx, ecx, &slow);
12277 12277
12278 // Check that the function prototype is a JS object. 12278 // Check that the function prototype is a JS object.
12279 __ test(ebx, Immediate(kSmiTagMask)); 12279 __ test(ebx, Immediate(kSmiTagMask));
12280 __ j(zero, &slow, not_taken); 12280 __ j(zero, &slow, not_taken);
12281 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); 12281 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
12282 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 12282 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
12283 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 12283 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
12284 __ j(less, &slow, not_taken); 12284 __ j(below, &slow, not_taken);
12285 __ cmp(ecx, LAST_JS_OBJECT_TYPE); 12285 __ cmp(ecx, LAST_JS_OBJECT_TYPE);
12286 __ j(greater, &slow, not_taken); 12286 __ j(above, &slow, not_taken);
12287 12287
12288 // Register mapping: 12288 // Register mapping:
12289 // eax is object map. 12289 // eax is object map.
12290 // edx is function. 12290 // edx is function.
12291 // ebx is function prototype. 12291 // ebx is function prototype.
12292 __ mov(ecx, Immediate(Heap::kInstanceofCacheMapRootIndex)); 12292 __ mov(ecx, Immediate(Heap::kInstanceofCacheMapRootIndex));
12293 __ mov(Operand::StaticArray(ecx, times_pointer_size, roots_address), eax); 12293 __ mov(Operand::StaticArray(ecx, times_pointer_size, roots_address), eax);
12294 __ mov(ecx, Immediate(Heap::kInstanceofCacheFunctionRootIndex)); 12294 __ mov(ecx, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
12295 __ mov(Operand::StaticArray(ecx, times_pointer_size, roots_address), edx); 12295 __ mov(Operand::StaticArray(ecx, times_pointer_size, roots_address), edx);
12296 12296
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
13276 // tagged as a small integer. 13276 // tagged as a small integer.
13277 __ bind(&runtime); 13277 __ bind(&runtime);
13278 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 13278 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
13279 } 13279 }
13280 13280
13281 #undef __ 13281 #undef __
13282 13282
13283 } } // namespace v8::internal 13283 } } // namespace v8::internal
13284 13284
13285 #endif // V8_TARGET_ARCH_IA32 13285 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698