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

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

Issue 2586001: Add test_b(Operand, immediate) to ia32 assembler, and use it where possible. ... (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/codegen-ia32.cc
===================================================================
--- src/ia32/codegen-ia32.cc (revision 4792)
+++ src/ia32/codegen-ia32.cc (working copy)
@@ -2624,9 +2624,8 @@
ASSERT(temp.is_valid());
__ mov(temp.reg(),
FieldOperand(operand.reg(), HeapObject::kMapOffset));
- __ movzx_b(temp.reg(),
- FieldOperand(temp.reg(), Map::kBitFieldOffset));
- __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
+ __ test_b(FieldOperand(temp.reg(), Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
temp.Unuse();
operand.Unuse();
dest->Split(not_zero);
@@ -2720,11 +2719,9 @@
// left_side is a sequential ASCII string.
left_side = Result(left_reg);
right_side = Result(right_val);
- Result temp2 = allocator_->Allocate();
- ASSERT(temp2.is_valid());
// Test string equality and comparison.
+ Label comparison_done;
if (cc == equal) {
- Label comparison_done;
__ cmp(FieldOperand(left_side.reg(), String::kLengthOffset),
Immediate(Smi::FromInt(1)));
__ j(not_equal, &comparison_done);
@@ -2732,34 +2729,25 @@
static_cast<uint8_t>(String::cast(*right_val)->Get(0));
__ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize),
char_value);
- __ bind(&comparison_done);
} else {
- __ mov(temp2.reg(),
- FieldOperand(left_side.reg(), String::kLengthOffset));
- __ SmiUntag(temp2.reg());
- __ sub(Operand(temp2.reg()), Immediate(1));
- Label comparison;
- // If the length is 0 then the subtraction gave -1 which compares less
- // than any character.
- __ j(negative, &comparison);
- // Otherwise load the first character.
- __ movzx_b(temp2.reg(),
- FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize));
- __ bind(&comparison);
+ __ cmp(FieldOperand(left_side.reg(), String::kLengthOffset),
+ Immediate(Smi::FromInt(1)));
+ // If the length is 0 then the jump is taken and the flags
+ // correctly represent being less than the one-character string.
+ __ j(below, &comparison_done);
// Compare the first character of the string with the
// constant 1-character string.
uint8_t char_value =
static_cast<uint8_t>(String::cast(*right_val)->Get(0));
- __ cmp(Operand(temp2.reg()), Immediate(char_value));
- Label characters_were_different;
- __ j(not_equal, &characters_were_different);
+ __ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize),
+ char_value);
+ __ j(not_equal, &comparison_done);
// If the first character is the same then the long string sorts after
// the short one.
__ cmp(FieldOperand(left_side.reg(), String::kLengthOffset),
Immediate(Smi::FromInt(1)));
- __ bind(&characters_were_different);
}
- temp2.Unuse();
+ __ bind(&comparison_done);
left_side.Unuse();
right_side.Unuse();
dest->Split(cc);
@@ -4148,9 +4136,7 @@
// eax: value to be iterated over
__ test(eax, Immediate(kSmiTagMask));
primitive.Branch(zero);
- __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
- __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+ __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
jsobject.Branch(above_equal);
primitive.Bind();
@@ -6317,14 +6303,15 @@
ASSERT(map.is_valid());
__ mov(map.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
// Undetectable objects behave like undefined when tested with typeof.
- __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kBitFieldOffset));
- __ test(map.reg(), Immediate(1 << Map::kIsUndetectable));
+ __ test_b(FieldOperand(map.reg(), Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
destination()->false_target()->Branch(not_zero);
- __ mov(map.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
+ // Do a range test for JSObject type. We can't use
+ // MacroAssembler::IsInstanceJSObjectType, because we are using a
+ // ControlDestination, so we copy its implementation here.
__ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kInstanceTypeOffset));
- __ cmp(map.reg(), FIRST_JS_OBJECT_TYPE);
- destination()->false_target()->Branch(below);
- __ cmp(map.reg(), LAST_JS_OBJECT_TYPE);
+ __ sub(Operand(map.reg()), Immediate(FIRST_JS_OBJECT_TYPE));
+ __ cmp(map.reg(), LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
obj.Unuse();
map.Unuse();
destination()->Split(below_equal);
@@ -6360,9 +6347,8 @@
ASSERT(temp.is_valid());
__ mov(temp.reg(),
FieldOperand(obj.reg(), HeapObject::kMapOffset));
- __ movzx_b(temp.reg(),
- FieldOperand(temp.reg(), Map::kBitFieldOffset));
- __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
+ __ test_b(FieldOperand(temp.reg(), Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
obj.Unuse();
temp.Unuse();
destination()->Split(not_zero);
@@ -6436,20 +6422,16 @@
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
- { Result tmp = allocator()->Allocate();
- __ mov(obj.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
- __ movzx_b(tmp.reg(), FieldOperand(obj.reg(), Map::kInstanceTypeOffset));
- __ cmp(tmp.reg(), FIRST_JS_OBJECT_TYPE);
- null.Branch(below);
+ __ CmpObjectType(obj.reg(), FIRST_JS_OBJECT_TYPE, obj.reg());
+ null.Branch(below);
- // As long as JS_FUNCTION_TYPE is the last instance type and it is
- // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
- // LAST_JS_OBJECT_TYPE.
- ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
- __ cmp(tmp.reg(), JS_FUNCTION_TYPE);
- function.Branch(equal);
- }
+ // As long as JS_FUNCTION_TYPE is the last instance type and it is
+ // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
+ // LAST_JS_OBJECT_TYPE.
+ ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
+ __ CmpInstanceType(obj.reg(), JS_FUNCTION_TYPE);
+ function.Branch(equal);
// Check if the constructor in the map is a function.
{ Result tmp = allocator()->Allocate();
@@ -7030,8 +7012,8 @@
// has no indexed interceptor.
__ CmpObjectType(object.reg(), FIRST_JS_OBJECT_TYPE, tmp1.reg());
deferred->Branch(below);
- __ movzx_b(tmp1.reg(), FieldOperand(tmp1.reg(), Map::kBitFieldOffset));
- __ test(tmp1.reg(), Immediate(KeyedLoadIC::kSlowCaseBitFieldMask));
+ __ test_b(FieldOperand(tmp1.reg(), Map::kBitFieldOffset),
+ KeyedLoadIC::kSlowCaseBitFieldMask);
deferred->Branch(not_zero);
// Check the object's elements are in fast case.
@@ -8285,10 +8267,10 @@
Result temp = allocator()->Allocate();
ASSERT(temp.is_valid());
__ mov(temp.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
- __ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kBitFieldOffset));
- __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
+ __ test_b(FieldOperand(temp.reg(), Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
destination()->false_target()->Branch(not_zero);
- __ CmpObjectType(answer.reg(), FIRST_NONSTRING_TYPE, temp.reg());
+ __ CmpInstanceType(temp.reg(), FIRST_NONSTRING_TYPE);
temp.Unuse();
answer.Unuse();
destination()->Split(below);
@@ -8310,9 +8292,8 @@
// It can be an undetectable object.
frame_->Spill(answer.reg());
__ mov(answer.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
- __ movzx_b(answer.reg(),
- FieldOperand(answer.reg(), Map::kBitFieldOffset));
- __ test(answer.reg(), Immediate(1 << Map::kIsUndetectable));
+ __ test_b(FieldOperand(answer.reg(), Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
answer.Unuse();
destination()->Split(not_zero);
@@ -8339,14 +8320,15 @@
destination()->false_target()->Branch(equal);
// It can be an undetectable object.
- __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kBitFieldOffset));
- __ test(map.reg(), Immediate(1 << Map::kIsUndetectable));
+ __ test_b(FieldOperand(map.reg(), Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
destination()->false_target()->Branch(not_zero);
- __ mov(map.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
+ // Do a range test for JSObject type. We can't use
+ // MacroAssembler::IsInstanceJSObjectType, because we are using a
+ // ControlDestination, so we copy its implementation here.
__ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kInstanceTypeOffset));
- __ cmp(map.reg(), FIRST_JS_OBJECT_TYPE);
- destination()->false_target()->Branch(below);
- __ cmp(map.reg(), LAST_JS_OBJECT_TYPE);
+ __ sub(Operand(map.reg()), Immediate(FIRST_JS_OBJECT_TYPE));
+ __ cmp(map.reg(), LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
answer.Unuse();
map.Unuse();
destination()->Split(below_equal);
@@ -9273,20 +9255,19 @@
__ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset));
// Undetectable => false.
- __ movzx_b(ebx, FieldOperand(edx, Map::kBitFieldOffset));
- __ and_(ebx, 1 << Map::kIsUndetectable);
+ __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
+ 1 << Map::kIsUndetectable);
__ j(not_zero, &false_result);
// JavaScript object => true.
- __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+ __ CmpInstanceType(edx, FIRST_JS_OBJECT_TYPE);
__ j(above_equal, &true_result);
// String value => false iff empty.
- __ cmp(ecx, FIRST_NONSTRING_TYPE);
+ __ CmpInstanceType(edx, FIRST_NONSTRING_TYPE);
__ j(above_equal, &not_string);
- __ mov(edx, FieldOperand(eax, String::kLengthOffset));
ASSERT(kSmiTag == 0);
- __ test(edx, Operand(edx));
+ __ cmp(FieldOperand(eax, String::kLengthOffset), Immediate(0));
__ j(zero, &false_result);
__ jmp(&true_result);
@@ -11742,13 +11723,10 @@
// There is no test for undetectability in strict equality.
// Get the type of the first operand.
- __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
-
// If the first object is a JS object, we have done pointer comparison.
- ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
Label first_non_object;
- __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+ ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
__ j(below, &first_non_object);
// Return non-zero (eax is not zero)
@@ -11759,17 +11737,14 @@
__ bind(&first_non_object);
// Check for oddballs: true, false, null, undefined.
- __ cmp(ecx, ODDBALL_TYPE);
+ __ CmpInstanceType(ecx, ODDBALL_TYPE);
__ j(equal, &return_not_equal);
- __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
-
- __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+ __ CmpObjectType(edx, FIRST_JS_OBJECT_TYPE, ecx);
__ j(above_equal, &return_not_equal);
// Check for oddballs: true, false, null, undefined.
- __ cmp(ecx, ODDBALL_TYPE);
+ __ CmpInstanceType(ecx, ODDBALL_TYPE);
__ j(equal, &return_not_equal);
// Fall through to the general case.
@@ -12411,12 +12386,7 @@
__ j(zero, &slow, not_taken);
// Check that the left hand is a JS object.
- __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); // eax - object map
- __ movzx_b(ecx, FieldOperand(eax, Map::kInstanceTypeOffset)); // ecx - type
- __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
- __ j(below, &slow, not_taken);
- __ cmp(ecx, LAST_JS_OBJECT_TYPE);
- __ j(above, &slow, not_taken);
+ __ IsObjectJSObjectType(eax, eax, edx, &slow);
// Get the prototype of the function.
__ mov(edx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
@@ -12441,12 +12411,7 @@
// Check that the function prototype is a JS object.
__ test(ebx, Immediate(kSmiTagMask));
__ j(zero, &slow, not_taken);
- __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
- __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
- __ j(below, &slow, not_taken);
- __ cmp(ecx, LAST_JS_OBJECT_TYPE);
- __ j(above, &slow, not_taken);
+ __ IsObjectJSObjectType(ebx, ecx, ecx, &slow);
// Register mapping:
// eax is object map.
@@ -12881,14 +12846,12 @@
// ebx: length of resulting flat string as a smi
// edx: second string
Label non_ascii_string_add_flat_result;
- __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
ASSERT(kStringEncodingMask == kAsciiStringTag);
- __ test(ecx, Immediate(kAsciiStringTag));
+ __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
+ __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
__ j(zero, &non_ascii_string_add_flat_result);
__ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
- __ test(ecx, Immediate(kAsciiStringTag));
+ __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
__ j(zero, &string_add_runtime);
__ bind(&make_flat_ascii_string);
@@ -12929,8 +12892,7 @@
// edx: second string
__ bind(&non_ascii_string_add_flat_result);
__ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
- __ and_(ecx, kAsciiStringTag);
+ __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
__ j(not_zero, &string_add_runtime);
// Both strings are two byte strings. As they are short they are both
// flat.
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698