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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 7191007: Cleanup: use JumpIf[Not]Smi() whenever we can (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: introduced new macro Created 9 years, 6 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/builtins-ia32.cc ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 25 matching lines...) Expand all
36 #include "regexp-macro-assembler.h" 36 #include "regexp-macro-assembler.h"
37 37
38 namespace v8 { 38 namespace v8 {
39 namespace internal { 39 namespace internal {
40 40
41 #define __ ACCESS_MASM(masm) 41 #define __ ACCESS_MASM(masm)
42 42
43 void ToNumberStub::Generate(MacroAssembler* masm) { 43 void ToNumberStub::Generate(MacroAssembler* masm) {
44 // The ToNumber stub takes one argument in eax. 44 // The ToNumber stub takes one argument in eax.
45 Label check_heap_number, call_builtin; 45 Label check_heap_number, call_builtin;
46 __ test(eax, Immediate(kSmiTagMask)); 46 __ JumpIfNotSmi(eax, &check_heap_number, Label::kNear);
47 __ j(not_zero, &check_heap_number, Label::kNear);
48 __ ret(0); 47 __ ret(0);
49 48
50 __ bind(&check_heap_number); 49 __ bind(&check_heap_number);
51 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 50 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
52 Factory* factory = masm->isolate()->factory(); 51 Factory* factory = masm->isolate()->factory();
53 __ cmp(Operand(ebx), Immediate(factory->heap_number_map())); 52 __ cmp(Operand(ebx), Immediate(factory->heap_number_map()));
54 __ j(not_equal, &call_builtin, Label::kNear); 53 __ j(not_equal, &call_builtin, Label::kNear);
55 __ ret(0); 54 __ ret(0);
56 55
57 __ bind(&call_builtin); 56 __ bind(&call_builtin);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 249
251 // Boolean -> its value 250 // Boolean -> its value
252 __ cmp(eax, factory->true_value()); 251 __ cmp(eax, factory->true_value());
253 __ j(equal, &true_result); 252 __ j(equal, &true_result);
254 __ cmp(eax, factory->false_value()); 253 __ cmp(eax, factory->false_value());
255 __ j(equal, &false_result); 254 __ j(equal, &false_result);
256 255
257 // Smis: 0 -> false, all other -> true 256 // Smis: 0 -> false, all other -> true
258 __ test(eax, Operand(eax)); 257 __ test(eax, Operand(eax));
259 __ j(zero, &false_result); 258 __ j(zero, &false_result);
260 __ test(eax, Immediate(kSmiTagMask)); 259 __ JumpIfSmi(eax, &true_result);
261 __ j(zero, &true_result);
262 260
263 // 'null' => false. 261 // 'null' => false.
264 __ cmp(eax, factory->null_value()); 262 __ cmp(eax, factory->null_value());
265 __ j(equal, &false_result, Label::kNear); 263 __ j(equal, &false_result, Label::kNear);
266 264
267 // Get the map and type of the heap object. 265 // Get the map and type of the heap object.
268 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 266 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
269 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset)); 267 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset));
270 268
271 // Undetectable => false. 269 // Undetectable => false.
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 609
612 610
613 void UnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm, 611 void UnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
614 Label* non_smi, 612 Label* non_smi,
615 Label* undo, 613 Label* undo,
616 Label* slow, 614 Label* slow,
617 Label::Distance non_smi_near, 615 Label::Distance non_smi_near,
618 Label::Distance undo_near, 616 Label::Distance undo_near,
619 Label::Distance slow_near) { 617 Label::Distance slow_near) {
620 // Check whether the value is a smi. 618 // Check whether the value is a smi.
621 __ test(eax, Immediate(kSmiTagMask)); 619 __ JumpIfNotSmi(eax, non_smi, non_smi_near);
622 __ j(not_zero, non_smi, non_smi_near);
623 620
624 // We can't handle -0 with smis, so use a type transition for that case. 621 // We can't handle -0 with smis, so use a type transition for that case.
625 __ test(eax, Operand(eax)); 622 __ test(eax, Operand(eax));
626 __ j(zero, slow, slow_near); 623 __ j(zero, slow, slow_near);
627 624
628 // Try optimistic subtraction '0 - value', saving operand in eax for undo. 625 // Try optimistic subtraction '0 - value', saving operand in eax for undo.
629 __ mov(edx, Operand(eax)); 626 __ mov(edx, Operand(eax));
630 __ Set(eax, Immediate(0)); 627 __ Set(eax, Immediate(0));
631 __ sub(eax, Operand(edx)); 628 __ sub(eax, Operand(edx));
632 __ j(overflow, undo, undo_near); 629 __ j(overflow, undo, undo_near);
633 __ ret(0); 630 __ ret(0);
634 } 631 }
635 632
636 633
637 void UnaryOpStub::GenerateSmiCodeBitNot( 634 void UnaryOpStub::GenerateSmiCodeBitNot(
638 MacroAssembler* masm, 635 MacroAssembler* masm,
639 Label* non_smi, 636 Label* non_smi,
640 Label::Distance non_smi_near) { 637 Label::Distance non_smi_near) {
641 // Check whether the value is a smi. 638 // Check whether the value is a smi.
642 __ test(eax, Immediate(kSmiTagMask)); 639 __ JumpIfNotSmi(eax, non_smi, non_smi_near);
643 __ j(not_zero, non_smi, non_smi_near);
644 640
645 // Flip bits and revert inverted smi-tag. 641 // Flip bits and revert inverted smi-tag.
646 __ not_(eax); 642 __ not_(eax);
647 __ and_(eax, ~kSmiTagMask); 643 __ and_(eax, ~kSmiTagMask);
648 __ ret(0); 644 __ ret(0);
649 } 645 }
650 646
651 647
652 void UnaryOpStub::GenerateSmiCodeUndo(MacroAssembler* masm) { 648 void UnaryOpStub::GenerateSmiCodeUndo(MacroAssembler* masm) {
653 __ mov(eax, Operand(edx)); 649 __ mov(eax, Operand(edx));
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 __ or_(right, Operand(left)); 995 __ or_(right, Operand(left));
1000 combined = right; 996 combined = right;
1001 break; 997 break;
1002 998
1003 default: 999 default:
1004 break; 1000 break;
1005 } 1001 }
1006 1002
1007 // 3. Perform the smi check of the operands. 1003 // 3. Perform the smi check of the operands.
1008 STATIC_ASSERT(kSmiTag == 0); // Adjust zero check if not the case. 1004 STATIC_ASSERT(kSmiTag == 0); // Adjust zero check if not the case.
1009 __ test(combined, Immediate(kSmiTagMask)); 1005 __ JumpIfNotSmi(combined, &not_smis);
1010 __ j(not_zero, &not_smis);
1011 1006
1012 // 4. Operands are both smis, perform the operation leaving the result in 1007 // 4. Operands are both smis, perform the operation leaving the result in
1013 // eax and check the result if necessary. 1008 // eax and check the result if necessary.
1014 Comment perform_smi(masm, "-- Perform smi operation"); 1009 Comment perform_smi(masm, "-- Perform smi operation");
1015 Label use_fp_on_smis; 1010 Label use_fp_on_smis;
1016 switch (op_) { 1011 switch (op_) {
1017 case Token::BIT_OR: 1012 case Token::BIT_OR:
1018 // Nothing to do. 1013 // Nothing to do.
1019 break; 1014 break;
1020 1015
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 ASSERT(operands_type_ == BinaryOpIC::BOTH_STRING); 1383 ASSERT(operands_type_ == BinaryOpIC::BOTH_STRING);
1389 ASSERT(op_ == Token::ADD); 1384 ASSERT(op_ == Token::ADD);
1390 // If both arguments are strings, call the string add stub. 1385 // If both arguments are strings, call the string add stub.
1391 // Otherwise, do a transition. 1386 // Otherwise, do a transition.
1392 1387
1393 // Registers containing left and right operands respectively. 1388 // Registers containing left and right operands respectively.
1394 Register left = edx; 1389 Register left = edx;
1395 Register right = eax; 1390 Register right = eax;
1396 1391
1397 // Test if left operand is a string. 1392 // Test if left operand is a string.
1398 __ test(left, Immediate(kSmiTagMask)); 1393 __ JumpIfSmi(left, &call_runtime);
1399 __ j(zero, &call_runtime);
1400 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); 1394 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
1401 __ j(above_equal, &call_runtime); 1395 __ j(above_equal, &call_runtime);
1402 1396
1403 // Test if right operand is a string. 1397 // Test if right operand is a string.
1404 __ test(right, Immediate(kSmiTagMask)); 1398 __ JumpIfSmi(right, &call_runtime);
1405 __ j(zero, &call_runtime);
1406 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); 1399 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx);
1407 __ j(above_equal, &call_runtime); 1400 __ j(above_equal, &call_runtime);
1408 1401
1409 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); 1402 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
1410 GenerateRegisterArgsPush(masm); 1403 GenerateRegisterArgsPush(masm);
1411 __ TailCallStub(&string_add_stub); 1404 __ TailCallStub(&string_add_stub);
1412 1405
1413 __ bind(&call_runtime); 1406 __ bind(&call_runtime);
1414 GenerateTypeTransition(masm); 1407 GenerateTypeTransition(masm);
1415 } 1408 }
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1531 // Allocate a heap number if needed. 1524 // Allocate a heap number if needed.
1532 __ mov(ebx, Operand(eax)); // ebx: result 1525 __ mov(ebx, Operand(eax)); // ebx: result
1533 Label skip_allocation; 1526 Label skip_allocation;
1534 switch (mode_) { 1527 switch (mode_) {
1535 case OVERWRITE_LEFT: 1528 case OVERWRITE_LEFT:
1536 case OVERWRITE_RIGHT: 1529 case OVERWRITE_RIGHT:
1537 // If the operand was an object, we skip the 1530 // If the operand was an object, we skip the
1538 // allocation of a heap number. 1531 // allocation of a heap number.
1539 __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ? 1532 __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ?
1540 1 * kPointerSize : 2 * kPointerSize)); 1533 1 * kPointerSize : 2 * kPointerSize));
1541 __ test(eax, Immediate(kSmiTagMask)); 1534 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear);
1542 __ j(not_zero, &skip_allocation, Label::kNear);
1543 // Fall through! 1535 // Fall through!
1544 case NO_OVERWRITE: 1536 case NO_OVERWRITE:
1545 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); 1537 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
1546 __ bind(&skip_allocation); 1538 __ bind(&skip_allocation);
1547 break; 1539 break;
1548 default: UNREACHABLE(); 1540 default: UNREACHABLE();
1549 } 1541 }
1550 // Store the result in the HeapNumber and return. 1542 // Store the result in the HeapNumber and return.
1551 if (CpuFeatures::IsSupported(SSE2)) { 1543 if (CpuFeatures::IsSupported(SSE2)) {
1552 CpuFeatures::Scope use_sse2(SSE2); 1544 CpuFeatures::Scope use_sse2(SSE2);
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1746 // Allocate a heap number if needed. 1738 // Allocate a heap number if needed.
1747 __ mov(ebx, Operand(eax)); // ebx: result 1739 __ mov(ebx, Operand(eax)); // ebx: result
1748 Label skip_allocation; 1740 Label skip_allocation;
1749 switch (mode_) { 1741 switch (mode_) {
1750 case OVERWRITE_LEFT: 1742 case OVERWRITE_LEFT:
1751 case OVERWRITE_RIGHT: 1743 case OVERWRITE_RIGHT:
1752 // If the operand was an object, we skip the 1744 // If the operand was an object, we skip the
1753 // allocation of a heap number. 1745 // allocation of a heap number.
1754 __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ? 1746 __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ?
1755 1 * kPointerSize : 2 * kPointerSize)); 1747 1 * kPointerSize : 2 * kPointerSize));
1756 __ test(eax, Immediate(kSmiTagMask)); 1748 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear);
1757 __ j(not_zero, &skip_allocation, Label::kNear);
1758 // Fall through! 1749 // Fall through!
1759 case NO_OVERWRITE: 1750 case NO_OVERWRITE:
1760 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); 1751 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
1761 __ bind(&skip_allocation); 1752 __ bind(&skip_allocation);
1762 break; 1753 break;
1763 default: UNREACHABLE(); 1754 default: UNREACHABLE();
1764 } 1755 }
1765 // Store the result in the HeapNumber and return. 1756 // Store the result in the HeapNumber and return.
1766 if (CpuFeatures::IsSupported(SSE2)) { 1757 if (CpuFeatures::IsSupported(SSE2)) {
1767 CpuFeatures::Scope use_sse2(SSE2); 1758 CpuFeatures::Scope use_sse2(SSE2);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 // Allocate a heap number if needed. 1937 // Allocate a heap number if needed.
1947 __ mov(ebx, Operand(eax)); // ebx: result 1938 __ mov(ebx, Operand(eax)); // ebx: result
1948 Label skip_allocation; 1939 Label skip_allocation;
1949 switch (mode_) { 1940 switch (mode_) {
1950 case OVERWRITE_LEFT: 1941 case OVERWRITE_LEFT:
1951 case OVERWRITE_RIGHT: 1942 case OVERWRITE_RIGHT:
1952 // If the operand was an object, we skip the 1943 // If the operand was an object, we skip the
1953 // allocation of a heap number. 1944 // allocation of a heap number.
1954 __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ? 1945 __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ?
1955 1 * kPointerSize : 2 * kPointerSize)); 1946 1 * kPointerSize : 2 * kPointerSize));
1956 __ test(eax, Immediate(kSmiTagMask)); 1947 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear);
1957 __ j(not_zero, &skip_allocation, Label::kNear);
1958 // Fall through! 1948 // Fall through!
1959 case NO_OVERWRITE: 1949 case NO_OVERWRITE:
1960 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); 1950 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
1961 __ bind(&skip_allocation); 1951 __ bind(&skip_allocation);
1962 break; 1952 break;
1963 default: UNREACHABLE(); 1953 default: UNREACHABLE();
1964 } 1954 }
1965 // Store the result in the HeapNumber and return. 1955 // Store the result in the HeapNumber and return.
1966 if (CpuFeatures::IsSupported(SSE2)) { 1956 if (CpuFeatures::IsSupported(SSE2)) {
1967 CpuFeatures::Scope use_sse2(SSE2); 1957 CpuFeatures::Scope use_sse2(SSE2);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2030 2020
2031 void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { 2021 void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
2032 ASSERT(op_ == Token::ADD); 2022 ASSERT(op_ == Token::ADD);
2033 Label left_not_string, call_runtime; 2023 Label left_not_string, call_runtime;
2034 2024
2035 // Registers containing left and right operands respectively. 2025 // Registers containing left and right operands respectively.
2036 Register left = edx; 2026 Register left = edx;
2037 Register right = eax; 2027 Register right = eax;
2038 2028
2039 // Test if left operand is a string. 2029 // Test if left operand is a string.
2040 __ test(left, Immediate(kSmiTagMask)); 2030 __ JumpIfSmi(left, &left_not_string, Label::kNear);
2041 __ j(zero, &left_not_string, Label::kNear);
2042 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); 2031 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
2043 __ j(above_equal, &left_not_string, Label::kNear); 2032 __ j(above_equal, &left_not_string, Label::kNear);
2044 2033
2045 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); 2034 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB);
2046 GenerateRegisterArgsPush(masm); 2035 GenerateRegisterArgsPush(masm);
2047 __ TailCallStub(&string_add_left_stub); 2036 __ TailCallStub(&string_add_left_stub);
2048 2037
2049 // Left operand is not a string, test right. 2038 // Left operand is not a string, test right.
2050 __ bind(&left_not_string); 2039 __ bind(&left_not_string);
2051 __ test(right, Immediate(kSmiTagMask)); 2040 __ JumpIfSmi(right, &call_runtime, Label::kNear);
2052 __ j(zero, &call_runtime, Label::kNear);
2053 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); 2041 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx);
2054 __ j(above_equal, &call_runtime, Label::kNear); 2042 __ j(above_equal, &call_runtime, Label::kNear);
2055 2043
2056 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); 2044 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB);
2057 GenerateRegisterArgsPush(masm); 2045 GenerateRegisterArgsPush(masm);
2058 __ TailCallStub(&string_add_right_stub); 2046 __ TailCallStub(&string_add_right_stub);
2059 2047
2060 // Neither argument is a string. 2048 // Neither argument is a string.
2061 __ bind(&call_runtime); 2049 __ bind(&call_runtime);
2062 } 2050 }
2063 2051
2064 2052
2065 void BinaryOpStub::GenerateHeapResultAllocation( 2053 void BinaryOpStub::GenerateHeapResultAllocation(
2066 MacroAssembler* masm, 2054 MacroAssembler* masm,
2067 Label* alloc_failure) { 2055 Label* alloc_failure) {
2068 Label skip_allocation; 2056 Label skip_allocation;
2069 OverwriteMode mode = mode_; 2057 OverwriteMode mode = mode_;
2070 switch (mode) { 2058 switch (mode) {
2071 case OVERWRITE_LEFT: { 2059 case OVERWRITE_LEFT: {
2072 // If the argument in edx is already an object, we skip the 2060 // If the argument in edx is already an object, we skip the
2073 // allocation of a heap number. 2061 // allocation of a heap number.
2074 __ test(edx, Immediate(kSmiTagMask)); 2062 __ JumpIfNotSmi(edx, &skip_allocation, Label::kNear);
2075 __ j(not_zero, &skip_allocation);
2076 // Allocate a heap number for the result. Keep eax and edx intact 2063 // Allocate a heap number for the result. Keep eax and edx intact
2077 // for the possible runtime call. 2064 // for the possible runtime call.
2078 __ AllocateHeapNumber(ebx, ecx, no_reg, alloc_failure); 2065 __ AllocateHeapNumber(ebx, ecx, no_reg, alloc_failure);
2079 // Now edx can be overwritten losing one of the arguments as we are 2066 // Now edx can be overwritten losing one of the arguments as we are
2080 // now done and will not need it any more. 2067 // now done and will not need it any more.
2081 __ mov(edx, Operand(ebx)); 2068 __ mov(edx, Operand(ebx));
2082 __ bind(&skip_allocation); 2069 __ bind(&skip_allocation);
2083 // Use object in edx as a result holder 2070 // Use object in edx as a result holder
2084 __ mov(eax, Operand(edx)); 2071 __ mov(eax, Operand(edx));
2085 break; 2072 break;
2086 } 2073 }
2087 case OVERWRITE_RIGHT: 2074 case OVERWRITE_RIGHT:
2088 // If the argument in eax is already an object, we skip the 2075 // If the argument in eax is already an object, we skip the
2089 // allocation of a heap number. 2076 // allocation of a heap number.
2090 __ test(eax, Immediate(kSmiTagMask)); 2077 __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear);
2091 __ j(not_zero, &skip_allocation);
2092 // Fall through! 2078 // Fall through!
2093 case NO_OVERWRITE: 2079 case NO_OVERWRITE:
2094 // Allocate a heap number for the result. Keep eax and edx intact 2080 // Allocate a heap number for the result. Keep eax and edx intact
2095 // for the possible runtime call. 2081 // for the possible runtime call.
2096 __ AllocateHeapNumber(ebx, ecx, no_reg, alloc_failure); 2082 __ AllocateHeapNumber(ebx, ecx, no_reg, alloc_failure);
2097 // Now eax can be overwritten losing one of the arguments as we are 2083 // Now eax can be overwritten losing one of the arguments as we are
2098 // now done and will not need it any more. 2084 // now done and will not need it any more.
2099 __ mov(eax, ebx); 2085 __ mov(eax, ebx);
2100 __ bind(&skip_allocation); 2086 __ bind(&skip_allocation);
2101 break; 2087 break;
(...skipping 26 matching lines...) Expand all
2128 2114
2129 Label runtime_call; 2115 Label runtime_call;
2130 Label runtime_call_clear_stack; 2116 Label runtime_call_clear_stack;
2131 Label skip_cache; 2117 Label skip_cache;
2132 const bool tagged = (argument_type_ == TAGGED); 2118 const bool tagged = (argument_type_ == TAGGED);
2133 if (tagged) { 2119 if (tagged) {
2134 // Test that eax is a number. 2120 // Test that eax is a number.
2135 Label input_not_smi; 2121 Label input_not_smi;
2136 Label loaded; 2122 Label loaded;
2137 __ mov(eax, Operand(esp, kPointerSize)); 2123 __ mov(eax, Operand(esp, kPointerSize));
2138 __ test(eax, Immediate(kSmiTagMask)); 2124 __ JumpIfNotSmi(eax, &input_not_smi, Label::kNear);
2139 __ j(not_zero, &input_not_smi, Label::kNear);
2140 // Input is a smi. Untag and load it onto the FPU stack. 2125 // Input is a smi. Untag and load it onto the FPU stack.
2141 // Then load the low and high words of the double into ebx, edx. 2126 // Then load the low and high words of the double into ebx, edx.
2142 STATIC_ASSERT(kSmiTagSize == 1); 2127 STATIC_ASSERT(kSmiTagSize == 1);
2143 __ sar(eax, 1); 2128 __ sar(eax, 1);
2144 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 2129 __ sub(Operand(esp), Immediate(2 * kPointerSize));
2145 __ mov(Operand(esp, 0), eax); 2130 __ mov(Operand(esp, 0), eax);
2146 __ fild_s(Operand(esp, 0)); 2131 __ fild_s(Operand(esp, 0));
2147 __ fst_d(Operand(esp, 0)); 2132 __ fst_d(Operand(esp, 0));
2148 __ pop(edx); 2133 __ pop(edx);
2149 __ pop(ebx); 2134 __ pop(ebx);
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
2407 // Output: eax, ecx are left and right integers for a bit op. 2392 // Output: eax, ecx are left and right integers for a bit op.
2408 void FloatingPointHelper::LoadUnknownsAsIntegers(MacroAssembler* masm, 2393 void FloatingPointHelper::LoadUnknownsAsIntegers(MacroAssembler* masm,
2409 bool use_sse3, 2394 bool use_sse3,
2410 Label* conversion_failure) { 2395 Label* conversion_failure) {
2411 // Check float operands. 2396 // Check float operands.
2412 Label arg1_is_object, check_undefined_arg1; 2397 Label arg1_is_object, check_undefined_arg1;
2413 Label arg2_is_object, check_undefined_arg2; 2398 Label arg2_is_object, check_undefined_arg2;
2414 Label load_arg2, done; 2399 Label load_arg2, done;
2415 2400
2416 // Test if arg1 is a Smi. 2401 // Test if arg1 is a Smi.
2417 __ test(edx, Immediate(kSmiTagMask)); 2402 __ JumpIfNotSmi(edx, &arg1_is_object);
2418 __ j(not_zero, &arg1_is_object);
2419 2403
2420 __ SmiUntag(edx); 2404 __ SmiUntag(edx);
2421 __ jmp(&load_arg2); 2405 __ jmp(&load_arg2);
2422 2406
2423 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). 2407 // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
2424 __ bind(&check_undefined_arg1); 2408 __ bind(&check_undefined_arg1);
2425 Factory* factory = masm->isolate()->factory(); 2409 Factory* factory = masm->isolate()->factory();
2426 __ cmp(edx, factory->undefined_value()); 2410 __ cmp(edx, factory->undefined_value());
2427 __ j(not_equal, conversion_failure); 2411 __ j(not_equal, conversion_failure);
2428 __ mov(edx, Immediate(0)); 2412 __ mov(edx, Immediate(0));
2429 __ jmp(&load_arg2); 2413 __ jmp(&load_arg2);
2430 2414
2431 __ bind(&arg1_is_object); 2415 __ bind(&arg1_is_object);
2432 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); 2416 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
2433 __ cmp(ebx, factory->heap_number_map()); 2417 __ cmp(ebx, factory->heap_number_map());
2434 __ j(not_equal, &check_undefined_arg1); 2418 __ j(not_equal, &check_undefined_arg1);
2435 2419
2436 // Get the untagged integer version of the edx heap number in ecx. 2420 // Get the untagged integer version of the edx heap number in ecx.
2437 IntegerConvert(masm, edx, use_sse3, conversion_failure); 2421 IntegerConvert(masm, edx, use_sse3, conversion_failure);
2438 __ mov(edx, ecx); 2422 __ mov(edx, ecx);
2439 2423
2440 // Here edx has the untagged integer, eax has a Smi or a heap number. 2424 // Here edx has the untagged integer, eax has a Smi or a heap number.
2441 __ bind(&load_arg2); 2425 __ bind(&load_arg2);
2442 2426
2443 // Test if arg2 is a Smi. 2427 // Test if arg2 is a Smi.
2444 __ test(eax, Immediate(kSmiTagMask)); 2428 __ JumpIfNotSmi(eax, &arg2_is_object);
2445 __ j(not_zero, &arg2_is_object);
2446 2429
2447 __ SmiUntag(eax); 2430 __ SmiUntag(eax);
2448 __ mov(ecx, eax); 2431 __ mov(ecx, eax);
2449 __ jmp(&done); 2432 __ jmp(&done);
2450 2433
2451 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). 2434 // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
2452 __ bind(&check_undefined_arg2); 2435 __ bind(&check_undefined_arg2);
2453 __ cmp(eax, factory->undefined_value()); 2436 __ cmp(eax, factory->undefined_value());
2454 __ j(not_equal, conversion_failure); 2437 __ j(not_equal, conversion_failure);
2455 __ mov(ecx, Immediate(0)); 2438 __ mov(ecx, Immediate(0));
(...skipping 15 matching lines...) Expand all
2471 bool use_sse3, 2454 bool use_sse3,
2472 Label* not_int32) { 2455 Label* not_int32) {
2473 return; 2456 return;
2474 } 2457 }
2475 2458
2476 2459
2477 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, 2460 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
2478 Register number) { 2461 Register number) {
2479 Label load_smi, done; 2462 Label load_smi, done;
2480 2463
2481 __ test(number, Immediate(kSmiTagMask)); 2464 __ JumpIfSmi(number, &load_smi, Label::kNear);
2482 __ j(zero, &load_smi, Label::kNear);
2483 __ fld_d(FieldOperand(number, HeapNumber::kValueOffset)); 2465 __ fld_d(FieldOperand(number, HeapNumber::kValueOffset));
2484 __ jmp(&done, Label::kNear); 2466 __ jmp(&done, Label::kNear);
2485 2467
2486 __ bind(&load_smi); 2468 __ bind(&load_smi);
2487 __ SmiUntag(number); 2469 __ SmiUntag(number);
2488 __ push(number); 2470 __ push(number);
2489 __ fild_s(Operand(esp, 0)); 2471 __ fild_s(Operand(esp, 0));
2490 __ pop(number); 2472 __ pop(number);
2491 2473
2492 __ bind(&done); 2474 __ bind(&done);
2493 } 2475 }
2494 2476
2495 2477
2496 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm) { 2478 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm) {
2497 Label load_smi_edx, load_eax, load_smi_eax, done; 2479 Label load_smi_edx, load_eax, load_smi_eax, done;
2498 // Load operand in edx into xmm0. 2480 // Load operand in edx into xmm0.
2499 __ test(edx, Immediate(kSmiTagMask)); 2481 __ JumpIfSmi(edx, &load_smi_edx, Label::kNear);
2500 // Argument in edx is a smi.
2501 __ j(zero, &load_smi_edx, Label::kNear);
2502 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset)); 2482 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
2503 2483
2504 __ bind(&load_eax); 2484 __ bind(&load_eax);
2505 // Load operand in eax into xmm1. 2485 // Load operand in eax into xmm1.
2506 __ test(eax, Immediate(kSmiTagMask)); 2486 __ JumpIfSmi(eax, &load_smi_eax, Label::kNear);
2507 // Argument in eax is a smi.
2508 __ j(zero, &load_smi_eax, Label::kNear);
2509 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 2487 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
2510 __ jmp(&done, Label::kNear); 2488 __ jmp(&done, Label::kNear);
2511 2489
2512 __ bind(&load_smi_edx); 2490 __ bind(&load_smi_edx);
2513 __ SmiUntag(edx); // Untag smi before converting to float. 2491 __ SmiUntag(edx); // Untag smi before converting to float.
2514 __ cvtsi2sd(xmm0, Operand(edx)); 2492 __ cvtsi2sd(xmm0, Operand(edx));
2515 __ SmiTag(edx); // Retag smi for heap number overwriting test. 2493 __ SmiTag(edx); // Retag smi for heap number overwriting test.
2516 __ jmp(&load_eax); 2494 __ jmp(&load_eax);
2517 2495
2518 __ bind(&load_smi_eax); 2496 __ bind(&load_smi_eax);
2519 __ SmiUntag(eax); // Untag smi before converting to float. 2497 __ SmiUntag(eax); // Untag smi before converting to float.
2520 __ cvtsi2sd(xmm1, Operand(eax)); 2498 __ cvtsi2sd(xmm1, Operand(eax));
2521 __ SmiTag(eax); // Retag smi for heap number overwriting test. 2499 __ SmiTag(eax); // Retag smi for heap number overwriting test.
2522 2500
2523 __ bind(&done); 2501 __ bind(&done);
2524 } 2502 }
2525 2503
2526 2504
2527 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm, 2505 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm,
2528 Label* not_numbers) { 2506 Label* not_numbers) {
2529 Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done; 2507 Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done;
2530 // Load operand in edx into xmm0, or branch to not_numbers. 2508 // Load operand in edx into xmm0, or branch to not_numbers.
2531 __ test(edx, Immediate(kSmiTagMask)); 2509 __ JumpIfSmi(edx, &load_smi_edx, Label::kNear);
2532 // Argument in edx is a smi.
2533 __ j(zero, &load_smi_edx, Label::kNear);
2534 Factory* factory = masm->isolate()->factory(); 2510 Factory* factory = masm->isolate()->factory();
2535 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), factory->heap_number_map()); 2511 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), factory->heap_number_map());
2536 __ j(not_equal, not_numbers); // Argument in edx is not a number. 2512 __ j(not_equal, not_numbers); // Argument in edx is not a number.
2537 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset)); 2513 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
2538 __ bind(&load_eax); 2514 __ bind(&load_eax);
2539 // Load operand in eax into xmm1, or branch to not_numbers. 2515 // Load operand in eax into xmm1, or branch to not_numbers.
2540 __ test(eax, Immediate(kSmiTagMask)); 2516 __ JumpIfSmi(eax, &load_smi_eax, Label::kNear);
2541 // Argument in eax is a smi.
2542 __ j(zero, &load_smi_eax, Label::kNear);
2543 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map()); 2517 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map());
2544 __ j(equal, &load_float_eax, Label::kNear); 2518 __ j(equal, &load_float_eax, Label::kNear);
2545 __ jmp(not_numbers); // Argument in eax is not a number. 2519 __ jmp(not_numbers); // Argument in eax is not a number.
2546 __ bind(&load_smi_edx); 2520 __ bind(&load_smi_edx);
2547 __ SmiUntag(edx); // Untag smi before converting to float. 2521 __ SmiUntag(edx); // Untag smi before converting to float.
2548 __ cvtsi2sd(xmm0, Operand(edx)); 2522 __ cvtsi2sd(xmm0, Operand(edx));
2549 __ SmiTag(edx); // Retag smi for heap number overwriting test. 2523 __ SmiTag(edx); // Retag smi for heap number overwriting test.
2550 __ jmp(&load_eax); 2524 __ jmp(&load_eax);
2551 __ bind(&load_smi_eax); 2525 __ bind(&load_smi_eax);
2552 __ SmiUntag(eax); // Untag smi before converting to float. 2526 __ SmiUntag(eax); // Untag smi before converting to float.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 2566
2593 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm, 2567 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm,
2594 Register scratch, 2568 Register scratch,
2595 ArgLocation arg_location) { 2569 ArgLocation arg_location) {
2596 Label load_smi_1, load_smi_2, done_load_1, done; 2570 Label load_smi_1, load_smi_2, done_load_1, done;
2597 if (arg_location == ARGS_IN_REGISTERS) { 2571 if (arg_location == ARGS_IN_REGISTERS) {
2598 __ mov(scratch, edx); 2572 __ mov(scratch, edx);
2599 } else { 2573 } else {
2600 __ mov(scratch, Operand(esp, 2 * kPointerSize)); 2574 __ mov(scratch, Operand(esp, 2 * kPointerSize));
2601 } 2575 }
2602 __ test(scratch, Immediate(kSmiTagMask)); 2576 __ JumpIfSmi(scratch, &load_smi_1, Label::kNear);
2603 __ j(zero, &load_smi_1, Label::kNear);
2604 __ fld_d(FieldOperand(scratch, HeapNumber::kValueOffset)); 2577 __ fld_d(FieldOperand(scratch, HeapNumber::kValueOffset));
2605 __ bind(&done_load_1); 2578 __ bind(&done_load_1);
2606 2579
2607 if (arg_location == ARGS_IN_REGISTERS) { 2580 if (arg_location == ARGS_IN_REGISTERS) {
2608 __ mov(scratch, eax); 2581 __ mov(scratch, eax);
2609 } else { 2582 } else {
2610 __ mov(scratch, Operand(esp, 1 * kPointerSize)); 2583 __ mov(scratch, Operand(esp, 1 * kPointerSize));
2611 } 2584 }
2612 __ test(scratch, Immediate(kSmiTagMask)); 2585 __ JumpIfSmi(scratch, &load_smi_2, Label::kNear);
2613 __ j(zero, &load_smi_2, Label::kNear);
2614 __ fld_d(FieldOperand(scratch, HeapNumber::kValueOffset)); 2586 __ fld_d(FieldOperand(scratch, HeapNumber::kValueOffset));
2615 __ jmp(&done, Label::kNear); 2587 __ jmp(&done, Label::kNear);
2616 2588
2617 __ bind(&load_smi_1); 2589 __ bind(&load_smi_1);
2618 __ SmiUntag(scratch); 2590 __ SmiUntag(scratch);
2619 __ push(scratch); 2591 __ push(scratch);
2620 __ fild_s(Operand(esp, 0)); 2592 __ fild_s(Operand(esp, 0));
2621 __ pop(scratch); 2593 __ pop(scratch);
2622 __ jmp(&done_load_1); 2594 __ jmp(&done_load_1);
2623 2595
(...skipping 24 matching lines...) Expand all
2648 __ pop(scratch); 2620 __ pop(scratch);
2649 } 2621 }
2650 2622
2651 2623
2652 void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm, 2624 void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm,
2653 Label* non_float, 2625 Label* non_float,
2654 Register scratch) { 2626 Register scratch) {
2655 Label test_other, done; 2627 Label test_other, done;
2656 // Test if both operands are floats or smi -> scratch=k_is_float; 2628 // Test if both operands are floats or smi -> scratch=k_is_float;
2657 // Otherwise scratch = k_not_float. 2629 // Otherwise scratch = k_not_float.
2658 __ test(edx, Immediate(kSmiTagMask)); 2630 __ JumpIfSmi(edx, &test_other, Label::kNear);
2659 __ j(zero, &test_other, Label::kNear); // argument in edx is OK
2660 __ mov(scratch, FieldOperand(edx, HeapObject::kMapOffset)); 2631 __ mov(scratch, FieldOperand(edx, HeapObject::kMapOffset));
2661 Factory* factory = masm->isolate()->factory(); 2632 Factory* factory = masm->isolate()->factory();
2662 __ cmp(scratch, factory->heap_number_map()); 2633 __ cmp(scratch, factory->heap_number_map());
2663 __ j(not_equal, non_float); // argument in edx is not a number -> NaN 2634 __ j(not_equal, non_float); // argument in edx is not a number -> NaN
2664 2635
2665 __ bind(&test_other); 2636 __ bind(&test_other);
2666 __ test(eax, Immediate(kSmiTagMask)); 2637 __ JumpIfSmi(eax, &done, Label::kNear);
2667 __ j(zero, &done, Label::kNear); // argument in eax is OK
2668 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset)); 2638 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset));
2669 __ cmp(scratch, factory->heap_number_map()); 2639 __ cmp(scratch, factory->heap_number_map());
2670 __ j(not_equal, non_float); // argument in eax is not a number -> NaN 2640 __ j(not_equal, non_float); // argument in eax is not a number -> NaN
2671 2641
2672 // Fall-through: Both operands are numbers. 2642 // Fall-through: Both operands are numbers.
2673 __ bind(&done); 2643 __ bind(&done);
2674 } 2644 }
2675 2645
2676 2646
2677 void FloatingPointHelper::CheckFloatOperandsAreInt32(MacroAssembler* masm, 2647 void FloatingPointHelper::CheckFloatOperandsAreInt32(MacroAssembler* masm,
(...skipping 15 matching lines...) Expand all
2693 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2663 __ mov(edx, Operand(esp, 2 * kPointerSize));
2694 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2664 __ mov(eax, Operand(esp, 1 * kPointerSize));
2695 2665
2696 // Save 1 in xmm3 - we need this several times later on. 2666 // Save 1 in xmm3 - we need this several times later on.
2697 __ mov(ecx, Immediate(1)); 2667 __ mov(ecx, Immediate(1));
2698 __ cvtsi2sd(xmm3, Operand(ecx)); 2668 __ cvtsi2sd(xmm3, Operand(ecx));
2699 2669
2700 Label exponent_nonsmi; 2670 Label exponent_nonsmi;
2701 Label base_nonsmi; 2671 Label base_nonsmi;
2702 // If the exponent is a heap number go to that specific case. 2672 // If the exponent is a heap number go to that specific case.
2703 __ test(eax, Immediate(kSmiTagMask)); 2673 __ JumpIfNotSmi(eax, &exponent_nonsmi);
2704 __ j(not_zero, &exponent_nonsmi); 2674 __ JumpIfNotSmi(edx, &base_nonsmi);
2705 __ test(edx, Immediate(kSmiTagMask));
2706 __ j(not_zero, &base_nonsmi);
2707 2675
2708 // Optimized version when both exponent and base are smis. 2676 // Optimized version when both exponent and base are smis.
2709 Label powi; 2677 Label powi;
2710 __ SmiUntag(edx); 2678 __ SmiUntag(edx);
2711 __ cvtsi2sd(xmm0, Operand(edx)); 2679 __ cvtsi2sd(xmm0, Operand(edx));
2712 __ jmp(&powi); 2680 __ jmp(&powi);
2713 // exponent is smi and base is a heapnumber. 2681 // exponent is smi and base is a heapnumber.
2714 __ bind(&base_nonsmi); 2682 __ bind(&base_nonsmi);
2715 Factory* factory = masm->isolate()->factory(); 2683 Factory* factory = masm->isolate()->factory();
2716 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2684 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2768 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 2736 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
2769 factory->heap_number_map()); 2737 factory->heap_number_map());
2770 __ j(not_equal, &call_runtime); 2738 __ j(not_equal, &call_runtime);
2771 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 2739 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
2772 // Test if exponent is nan. 2740 // Test if exponent is nan.
2773 __ ucomisd(xmm1, xmm1); 2741 __ ucomisd(xmm1, xmm1);
2774 __ j(parity_even, &call_runtime); 2742 __ j(parity_even, &call_runtime);
2775 2743
2776 Label base_not_smi; 2744 Label base_not_smi;
2777 Label handle_special_cases; 2745 Label handle_special_cases;
2778 __ test(edx, Immediate(kSmiTagMask)); 2746 __ JumpIfNotSmi(edx, &base_not_smi, Label::kNear);
2779 __ j(not_zero, &base_not_smi, Label::kNear);
2780 __ SmiUntag(edx); 2747 __ SmiUntag(edx);
2781 __ cvtsi2sd(xmm0, Operand(edx)); 2748 __ cvtsi2sd(xmm0, Operand(edx));
2782 __ jmp(&handle_special_cases, Label::kNear); 2749 __ jmp(&handle_special_cases, Label::kNear);
2783 2750
2784 __ bind(&base_not_smi); 2751 __ bind(&base_not_smi);
2785 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2752 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2786 factory->heap_number_map()); 2753 factory->heap_number_map());
2787 __ j(not_equal, &call_runtime); 2754 __ j(not_equal, &call_runtime);
2788 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset)); 2755 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset));
2789 __ and_(ecx, HeapNumber::kExponentMask); 2756 __ and_(ecx, HeapNumber::kExponentMask);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2841 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { 2808 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
2842 // The key is in edx and the parameter count is in eax. 2809 // The key is in edx and the parameter count is in eax.
2843 2810
2844 // The displacement is used for skipping the frame pointer on the 2811 // The displacement is used for skipping the frame pointer on the
2845 // stack. It is the offset of the last parameter (if any) relative 2812 // stack. It is the offset of the last parameter (if any) relative
2846 // to the frame pointer. 2813 // to the frame pointer.
2847 static const int kDisplacement = 1 * kPointerSize; 2814 static const int kDisplacement = 1 * kPointerSize;
2848 2815
2849 // Check that the key is a smi. 2816 // Check that the key is a smi.
2850 Label slow; 2817 Label slow;
2851 __ test(edx, Immediate(kSmiTagMask)); 2818 __ JumpIfNotSmi(edx, &slow);
2852 __ j(not_zero, &slow);
2853 2819
2854 // Check if the calling frame is an arguments adaptor frame. 2820 // Check if the calling frame is an arguments adaptor frame.
2855 Label adaptor; 2821 Label adaptor;
2856 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2822 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2857 __ mov(ecx, Operand(ebx, StandardFrameConstants::kContextOffset)); 2823 __ mov(ecx, Operand(ebx, StandardFrameConstants::kContextOffset));
2858 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2824 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2859 __ j(equal, &adaptor, Label::kNear); 2825 __ j(equal, &adaptor, Label::kNear);
2860 2826
2861 // Check index against formal parameters count limit passed in 2827 // Check index against formal parameters count limit passed in
2862 // through register eax. Use unsigned comparison to get negative 2828 // through register eax. Use unsigned comparison to get negative
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 masm->isolate()); 3005 masm->isolate());
3040 ExternalReference address_of_regexp_stack_memory_size = 3006 ExternalReference address_of_regexp_stack_memory_size =
3041 ExternalReference::address_of_regexp_stack_memory_size(masm->isolate()); 3007 ExternalReference::address_of_regexp_stack_memory_size(masm->isolate());
3042 __ mov(ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); 3008 __ mov(ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
3043 __ test(ebx, Operand(ebx)); 3009 __ test(ebx, Operand(ebx));
3044 __ j(zero, &runtime); 3010 __ j(zero, &runtime);
3045 3011
3046 // Check that the first argument is a JSRegExp object. 3012 // Check that the first argument is a JSRegExp object.
3047 __ mov(eax, Operand(esp, kJSRegExpOffset)); 3013 __ mov(eax, Operand(esp, kJSRegExpOffset));
3048 STATIC_ASSERT(kSmiTag == 0); 3014 STATIC_ASSERT(kSmiTag == 0);
3049 __ test(eax, Immediate(kSmiTagMask)); 3015 __ JumpIfSmi(eax, &runtime);
3050 __ j(zero, &runtime);
3051 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); 3016 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx);
3052 __ j(not_equal, &runtime); 3017 __ j(not_equal, &runtime);
3053 // Check that the RegExp has been compiled (data contains a fixed array). 3018 // Check that the RegExp has been compiled (data contains a fixed array).
3054 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); 3019 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
3055 if (FLAG_debug_code) { 3020 if (FLAG_debug_code) {
3056 __ test(ecx, Immediate(kSmiTagMask)); 3021 __ test(ecx, Immediate(kSmiTagMask));
3057 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected"); 3022 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected");
3058 __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx); 3023 __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx);
3059 __ Check(equal, "Unexpected type for RegExp data, FixedArray expected"); 3024 __ Check(equal, "Unexpected type for RegExp data, FixedArray expected");
3060 } 3025 }
(...skipping 13 matching lines...) Expand all
3074 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 3039 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
3075 __ add(Operand(edx), Immediate(2)); // edx was a smi. 3040 __ add(Operand(edx), Immediate(2)); // edx was a smi.
3076 // Check that the static offsets vector buffer is large enough. 3041 // Check that the static offsets vector buffer is large enough.
3077 __ cmp(edx, OffsetsVector::kStaticOffsetsVectorSize); 3042 __ cmp(edx, OffsetsVector::kStaticOffsetsVectorSize);
3078 __ j(above, &runtime); 3043 __ j(above, &runtime);
3079 3044
3080 // ecx: RegExp data (FixedArray) 3045 // ecx: RegExp data (FixedArray)
3081 // edx: Number of capture registers 3046 // edx: Number of capture registers
3082 // Check that the second argument is a string. 3047 // Check that the second argument is a string.
3083 __ mov(eax, Operand(esp, kSubjectOffset)); 3048 __ mov(eax, Operand(esp, kSubjectOffset));
3084 __ test(eax, Immediate(kSmiTagMask)); 3049 __ JumpIfSmi(eax, &runtime);
3085 __ j(zero, &runtime);
3086 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); 3050 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
3087 __ j(NegateCondition(is_string), &runtime); 3051 __ j(NegateCondition(is_string), &runtime);
3088 // Get the length of the string to ebx. 3052 // Get the length of the string to ebx.
3089 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); 3053 __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
3090 3054
3091 // ebx: Length of subject string as a smi 3055 // ebx: Length of subject string as a smi
3092 // ecx: RegExp data (FixedArray) 3056 // ecx: RegExp data (FixedArray)
3093 // edx: Number of capture registers 3057 // edx: Number of capture registers
3094 // Check that the third argument is a positive smi less than the subject 3058 // Check that the third argument is a positive smi less than the subject
3095 // string length. A negative value will be greater (unsigned comparison). 3059 // string length. A negative value will be greater (unsigned comparison).
3096 __ mov(eax, Operand(esp, kPreviousIndexOffset)); 3060 __ mov(eax, Operand(esp, kPreviousIndexOffset));
3097 __ test(eax, Immediate(kSmiTagMask)); 3061 __ JumpIfNotSmi(eax, &runtime);
3098 __ j(not_zero, &runtime);
3099 __ cmp(eax, Operand(ebx)); 3062 __ cmp(eax, Operand(ebx));
3100 __ j(above_equal, &runtime); 3063 __ j(above_equal, &runtime);
3101 3064
3102 // ecx: RegExp data (FixedArray) 3065 // ecx: RegExp data (FixedArray)
3103 // edx: Number of capture registers 3066 // edx: Number of capture registers
3104 // Check that the fourth object is a JSArray object. 3067 // Check that the fourth object is a JSArray object.
3105 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); 3068 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
3106 __ test(eax, Immediate(kSmiTagMask)); 3069 __ JumpIfSmi(eax, &runtime);
3107 __ j(zero, &runtime);
3108 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx); 3070 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
3109 __ j(not_equal, &runtime); 3071 __ j(not_equal, &runtime);
3110 // Check that the JSArray is in fast case. 3072 // Check that the JSArray is in fast case.
3111 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); 3073 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset));
3112 __ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset)); 3074 __ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset));
3113 Factory* factory = masm->isolate()->factory(); 3075 Factory* factory = masm->isolate()->factory();
3114 __ cmp(eax, factory->fixed_array_map()); 3076 __ cmp(eax, factory->fixed_array_map());
3115 __ j(not_equal, &runtime); 3077 __ j(not_equal, &runtime);
3116 // Check that the last match info has space for the capture registers and the 3078 // Check that the last match info has space for the capture registers and the
3117 // additional information. 3079 // additional information.
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
3369 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 3331 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
3370 #endif // V8_INTERPRETED_REGEXP 3332 #endif // V8_INTERPRETED_REGEXP
3371 } 3333 }
3372 3334
3373 3335
3374 void RegExpConstructResultStub::Generate(MacroAssembler* masm) { 3336 void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
3375 const int kMaxInlineLength = 100; 3337 const int kMaxInlineLength = 100;
3376 Label slowcase; 3338 Label slowcase;
3377 Label done; 3339 Label done;
3378 __ mov(ebx, Operand(esp, kPointerSize * 3)); 3340 __ mov(ebx, Operand(esp, kPointerSize * 3));
3379 __ test(ebx, Immediate(kSmiTagMask)); 3341 __ JumpIfNotSmi(ebx, &slowcase);
3380 __ j(not_zero, &slowcase);
3381 __ cmp(Operand(ebx), Immediate(Smi::FromInt(kMaxInlineLength))); 3342 __ cmp(Operand(ebx), Immediate(Smi::FromInt(kMaxInlineLength)));
3382 __ j(above, &slowcase); 3343 __ j(above, &slowcase);
3383 // Smi-tagging is equivalent to multiplying by 2. 3344 // Smi-tagging is equivalent to multiplying by 2.
3384 STATIC_ASSERT(kSmiTag == 0); 3345 STATIC_ASSERT(kSmiTag == 0);
3385 STATIC_ASSERT(kSmiTagSize == 1); 3346 STATIC_ASSERT(kSmiTagSize == 1);
3386 // Allocate RegExpResult followed by FixedArray with size in ebx. 3347 // Allocate RegExpResult followed by FixedArray with size in ebx.
3387 // JSArray: [Map][empty properties][Elements][Length-smi][index][input] 3348 // JSArray: [Map][empty properties][Elements][Length-smi][index][input]
3388 // Elements: [Map][Length][..elements..] 3349 // Elements: [Map][Length][..elements..]
3389 __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize, 3350 __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize,
3390 times_half_pointer_size, 3351 times_half_pointer_size,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3482 // doubles is the xor of the upper and lower words. See 3443 // doubles is the xor of the upper and lower words. See
3483 // Heap::GetNumberStringCache. 3444 // Heap::GetNumberStringCache.
3484 Label smi_hash_calculated; 3445 Label smi_hash_calculated;
3485 Label load_result_from_cache; 3446 Label load_result_from_cache;
3486 if (object_is_smi) { 3447 if (object_is_smi) {
3487 __ mov(scratch, object); 3448 __ mov(scratch, object);
3488 __ SmiUntag(scratch); 3449 __ SmiUntag(scratch);
3489 } else { 3450 } else {
3490 Label not_smi; 3451 Label not_smi;
3491 STATIC_ASSERT(kSmiTag == 0); 3452 STATIC_ASSERT(kSmiTag == 0);
3492 __ test(object, Immediate(kSmiTagMask)); 3453 __ JumpIfNotSmi(object, &not_smi, Label::kNear);
3493 __ j(not_zero, &not_smi, Label::kNear);
3494 __ mov(scratch, object); 3454 __ mov(scratch, object);
3495 __ SmiUntag(scratch); 3455 __ SmiUntag(scratch);
3496 __ jmp(&smi_hash_calculated, Label::kNear); 3456 __ jmp(&smi_hash_calculated, Label::kNear);
3497 __ bind(&not_smi); 3457 __ bind(&not_smi);
3498 __ cmp(FieldOperand(object, HeapObject::kMapOffset), 3458 __ cmp(FieldOperand(object, HeapObject::kMapOffset),
3499 masm->isolate()->factory()->heap_number_map()); 3459 masm->isolate()->factory()->heap_number_map());
3500 __ j(not_equal, not_found); 3460 __ j(not_equal, not_found);
3501 STATIC_ASSERT(8 == kDoubleSize); 3461 STATIC_ASSERT(8 == kDoubleSize);
3502 __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset)); 3462 __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset));
3503 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); 3463 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
3504 // Object is heap number and hash is now in scratch. Calculate cache index. 3464 // Object is heap number and hash is now in scratch. Calculate cache index.
3505 __ and_(scratch, Operand(mask)); 3465 __ and_(scratch, Operand(mask));
3506 Register index = scratch; 3466 Register index = scratch;
3507 Register probe = mask; 3467 Register probe = mask;
3508 __ mov(probe, 3468 __ mov(probe,
3509 FieldOperand(number_string_cache, 3469 FieldOperand(number_string_cache,
3510 index, 3470 index,
3511 times_twice_pointer_size, 3471 times_twice_pointer_size,
3512 FixedArray::kHeaderSize)); 3472 FixedArray::kHeaderSize));
3513 __ test(probe, Immediate(kSmiTagMask)); 3473 __ JumpIfSmi(probe, not_found);
3514 __ j(zero, not_found);
3515 if (CpuFeatures::IsSupported(SSE2)) { 3474 if (CpuFeatures::IsSupported(SSE2)) {
3516 CpuFeatures::Scope fscope(SSE2); 3475 CpuFeatures::Scope fscope(SSE2);
3517 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); 3476 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
3518 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); 3477 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset));
3519 __ ucomisd(xmm0, xmm1); 3478 __ ucomisd(xmm0, xmm1);
3520 } else { 3479 } else {
3521 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset)); 3480 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset));
3522 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset)); 3481 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset));
3523 __ FCmp(); 3482 __ FCmp();
3524 } 3483 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3576 void CompareStub::Generate(MacroAssembler* masm) { 3535 void CompareStub::Generate(MacroAssembler* masm) {
3577 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); 3536 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
3578 3537
3579 Label check_unequal_objects, done; 3538 Label check_unequal_objects, done;
3580 3539
3581 // Compare two smis if required. 3540 // Compare two smis if required.
3582 if (include_smi_compare_) { 3541 if (include_smi_compare_) {
3583 Label non_smi, smi_done; 3542 Label non_smi, smi_done;
3584 __ mov(ecx, Operand(edx)); 3543 __ mov(ecx, Operand(edx));
3585 __ or_(ecx, Operand(eax)); 3544 __ or_(ecx, Operand(eax));
3586 __ test(ecx, Immediate(kSmiTagMask)); 3545 __ JumpIfNotSmi(ecx, &non_smi);
3587 __ j(not_zero, &non_smi);
3588 __ sub(edx, Operand(eax)); // Return on the result of the subtraction. 3546 __ sub(edx, Operand(eax)); // Return on the result of the subtraction.
3589 __ j(no_overflow, &smi_done); 3547 __ j(no_overflow, &smi_done);
3590 __ not_(edx); // Correct sign in case of overflow. edx is never 0 here. 3548 __ not_(edx); // Correct sign in case of overflow. edx is never 0 here.
3591 __ bind(&smi_done); 3549 __ bind(&smi_done);
3592 __ mov(eax, edx); 3550 __ mov(eax, edx);
3593 __ ret(0); 3551 __ ret(0);
3594 __ bind(&non_smi); 3552 __ bind(&non_smi);
3595 } else if (FLAG_debug_code) { 3553 } else if (FLAG_debug_code) {
3596 __ mov(ecx, Operand(edx)); 3554 __ mov(ecx, Operand(edx));
3597 __ or_(ecx, Operand(eax)); 3555 __ or_(ecx, Operand(eax));
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
3903 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 3861 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
3904 // tagged as a small integer. 3862 // tagged as a small integer.
3905 __ InvokeBuiltin(builtin, JUMP_FUNCTION); 3863 __ InvokeBuiltin(builtin, JUMP_FUNCTION);
3906 } 3864 }
3907 3865
3908 3866
3909 void CompareStub::BranchIfNonSymbol(MacroAssembler* masm, 3867 void CompareStub::BranchIfNonSymbol(MacroAssembler* masm,
3910 Label* label, 3868 Label* label,
3911 Register object, 3869 Register object,
3912 Register scratch) { 3870 Register scratch) {
3913 __ test(object, Immediate(kSmiTagMask)); 3871 __ JumpIfSmi(object, label);
3914 __ j(zero, label);
3915 __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset)); 3872 __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset));
3916 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 3873 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
3917 __ and_(scratch, kIsSymbolMask | kIsNotStringMask); 3874 __ and_(scratch, kIsSymbolMask | kIsNotStringMask);
3918 __ cmp(scratch, kSymbolTag | kStringTag); 3875 __ cmp(scratch, kSymbolTag | kStringTag);
3919 __ j(not_equal, label); 3876 __ j(not_equal, label);
3920 } 3877 }
3921 3878
3922 3879
3923 void StackCheckStub::Generate(MacroAssembler* masm) { 3880 void StackCheckStub::Generate(MacroAssembler* masm) {
3924 __ TailCallRuntime(Runtime::kStackGuard, 0, 1); 3881 __ TailCallRuntime(Runtime::kStackGuard, 0, 1);
(...skipping 19 matching lines...) Expand all
3944 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 3901 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
3945 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), ebx); 3902 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), ebx);
3946 __ bind(&call); 3903 __ bind(&call);
3947 } 3904 }
3948 3905
3949 // Get the function to call from the stack. 3906 // Get the function to call from the stack.
3950 // +2 ~ receiver, return address 3907 // +2 ~ receiver, return address
3951 __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize)); 3908 __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize));
3952 3909
3953 // Check that the function really is a JavaScript function. 3910 // Check that the function really is a JavaScript function.
3954 __ test(edi, Immediate(kSmiTagMask)); 3911 __ JumpIfSmi(edi, &slow);
3955 __ j(zero, &slow);
3956 // Goto slow case if we do not have a function. 3912 // Goto slow case if we do not have a function.
3957 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 3913 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
3958 __ j(not_equal, &slow); 3914 __ j(not_equal, &slow);
3959 3915
3960 // Fast-case: Just invoke the function. 3916 // Fast-case: Just invoke the function.
3961 ParameterCount actual(argc_); 3917 ParameterCount actual(argc_);
3962 3918
3963 if (ReceiverMightBeImplicit()) { 3919 if (ReceiverMightBeImplicit()) {
3964 Label call_as_function; 3920 Label call_as_function;
3965 __ cmp(eax, masm->isolate()->factory()->the_hole_value()); 3921 __ cmp(eax, masm->isolate()->factory()->the_hole_value());
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
4344 ASSERT_EQ(function.code(), InstanceofStub::right().code()); 4300 ASSERT_EQ(function.code(), InstanceofStub::right().code());
4345 4301
4346 // Get the object and function - they are always both needed. 4302 // Get the object and function - they are always both needed.
4347 Label slow, not_js_object; 4303 Label slow, not_js_object;
4348 if (!HasArgsInRegisters()) { 4304 if (!HasArgsInRegisters()) {
4349 __ mov(object, Operand(esp, 2 * kPointerSize)); 4305 __ mov(object, Operand(esp, 2 * kPointerSize));
4350 __ mov(function, Operand(esp, 1 * kPointerSize)); 4306 __ mov(function, Operand(esp, 1 * kPointerSize));
4351 } 4307 }
4352 4308
4353 // Check that the left hand is a JS object. 4309 // Check that the left hand is a JS object.
4354 __ test(object, Immediate(kSmiTagMask)); 4310 __ JumpIfSmi(object, &not_js_object);
4355 __ j(zero, &not_js_object);
4356 __ IsObjectJSObjectType(object, map, scratch, &not_js_object); 4311 __ IsObjectJSObjectType(object, map, scratch, &not_js_object);
4357 4312
4358 // If there is a call site cache don't look in the global cache, but do the 4313 // If there is a call site cache don't look in the global cache, but do the
4359 // real lookup and update the call site cache. 4314 // real lookup and update the call site cache.
4360 if (!HasCallSiteInlineCheck()) { 4315 if (!HasCallSiteInlineCheck()) {
4361 // Look up the function and the map in the instanceof cache. 4316 // Look up the function and the map in the instanceof cache.
4362 Label miss; 4317 Label miss;
4363 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex)); 4318 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
4364 __ cmp(function, 4319 __ cmp(function,
4365 Operand::StaticArray(scratch, times_pointer_size, roots_address)); 4320 Operand::StaticArray(scratch, times_pointer_size, roots_address));
4366 __ j(not_equal, &miss, Label::kNear); 4321 __ j(not_equal, &miss, Label::kNear);
4367 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex)); 4322 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex));
4368 __ cmp(map, Operand::StaticArray( 4323 __ cmp(map, Operand::StaticArray(
4369 scratch, times_pointer_size, roots_address)); 4324 scratch, times_pointer_size, roots_address));
4370 __ j(not_equal, &miss, Label::kNear); 4325 __ j(not_equal, &miss, Label::kNear);
4371 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 4326 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
4372 __ mov(eax, Operand::StaticArray( 4327 __ mov(eax, Operand::StaticArray(
4373 scratch, times_pointer_size, roots_address)); 4328 scratch, times_pointer_size, roots_address));
4374 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 4329 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
4375 __ bind(&miss); 4330 __ bind(&miss);
4376 } 4331 }
4377 4332
4378 // Get the prototype of the function. 4333 // Get the prototype of the function.
4379 __ TryGetFunctionPrototype(function, prototype, scratch, &slow); 4334 __ TryGetFunctionPrototype(function, prototype, scratch, &slow);
4380 4335
4381 // Check that the function prototype is a JS object. 4336 // Check that the function prototype is a JS object.
4382 __ test(prototype, Immediate(kSmiTagMask)); 4337 __ JumpIfSmi(prototype, &slow);
4383 __ j(zero, &slow);
4384 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow); 4338 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
4385 4339
4386 // Update the global instanceof or call site inlined cache with the current 4340 // Update the global instanceof or call site inlined cache with the current
4387 // map and function. The cached answer will be set when it is known below. 4341 // map and function. The cached answer will be set when it is known below.
4388 if (!HasCallSiteInlineCheck()) { 4342 if (!HasCallSiteInlineCheck()) {
4389 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex)); 4343 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex));
4390 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_address), map); 4344 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_address), map);
4391 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex)); 4345 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
4392 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_address), 4346 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_address),
4393 function); 4347 function);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
4462 if (!ReturnTrueFalseObject()) { 4416 if (!ReturnTrueFalseObject()) {
4463 __ Set(eax, Immediate(Smi::FromInt(1))); 4417 __ Set(eax, Immediate(Smi::FromInt(1)));
4464 } 4418 }
4465 } 4419 }
4466 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 4420 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
4467 4421
4468 Label object_not_null, object_not_null_or_smi; 4422 Label object_not_null, object_not_null_or_smi;
4469 __ bind(&not_js_object); 4423 __ bind(&not_js_object);
4470 // Before null, smi and string value checks, check that the rhs is a function 4424 // Before null, smi and string value checks, check that the rhs is a function
4471 // as for a non-function rhs an exception needs to be thrown. 4425 // as for a non-function rhs an exception needs to be thrown.
4472 __ test(function, Immediate(kSmiTagMask)); 4426 __ JumpIfSmi(function, &slow);
4473 __ j(zero, &slow);
4474 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); 4427 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
4475 __ j(not_equal, &slow); 4428 __ j(not_equal, &slow);
4476 4429
4477 // Null is not instance of anything. 4430 // Null is not instance of anything.
4478 __ cmp(object, factory->null_value()); 4431 __ cmp(object, factory->null_value());
4479 __ j(not_equal, &object_not_null); 4432 __ j(not_equal, &object_not_null);
4480 __ Set(eax, Immediate(Smi::FromInt(1))); 4433 __ Set(eax, Immediate(Smi::FromInt(1)));
4481 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 4434 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
4482 4435
4483 __ bind(&object_not_null); 4436 __ bind(&object_not_null);
4484 // Smi values is not instance of anything. 4437 // Smi values is not instance of anything.
4485 __ test(object, Immediate(kSmiTagMask)); 4438 __ JumpIfNotSmi(object, &object_not_null_or_smi);
4486 __ j(not_zero, &object_not_null_or_smi);
4487 __ Set(eax, Immediate(Smi::FromInt(1))); 4439 __ Set(eax, Immediate(Smi::FromInt(1)));
4488 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 4440 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
4489 4441
4490 __ bind(&object_not_null_or_smi); 4442 __ bind(&object_not_null_or_smi);
4491 // String values is not instance of anything. 4443 // String values is not instance of anything.
4492 Condition is_string = masm->IsObjectStringType(object, scratch, scratch); 4444 Condition is_string = masm->IsObjectStringType(object, scratch, scratch);
4493 __ j(NegateCondition(is_string), &slow); 4445 __ j(NegateCondition(is_string), &slow);
4494 __ Set(eax, Immediate(Smi::FromInt(1))); 4446 __ Set(eax, Immediate(Smi::FromInt(1)));
4495 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 4447 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
4496 4448
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
4603 // ------------------------------------------------------------------------- 4555 // -------------------------------------------------------------------------
4604 // StringCharCodeAtGenerator 4556 // StringCharCodeAtGenerator
4605 4557
4606 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 4558 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
4607 Label flat_string; 4559 Label flat_string;
4608 Label ascii_string; 4560 Label ascii_string;
4609 Label got_char_code; 4561 Label got_char_code;
4610 4562
4611 // If the receiver is a smi trigger the non-string case. 4563 // If the receiver is a smi trigger the non-string case.
4612 STATIC_ASSERT(kSmiTag == 0); 4564 STATIC_ASSERT(kSmiTag == 0);
4613 __ test(object_, Immediate(kSmiTagMask)); 4565 __ JumpIfSmi(object_, receiver_not_string_);
4614 __ j(zero, receiver_not_string_);
4615 4566
4616 // Fetch the instance type of the receiver into result register. 4567 // Fetch the instance type of the receiver into result register.
4617 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4568 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4618 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4569 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4619 // If the receiver is not a string trigger the non-string case. 4570 // If the receiver is not a string trigger the non-string case.
4620 __ test(result_, Immediate(kIsNotStringMask)); 4571 __ test(result_, Immediate(kIsNotStringMask));
4621 __ j(not_zero, receiver_not_string_); 4572 __ j(not_zero, receiver_not_string_);
4622 4573
4623 // If the index is non-smi trigger the non-smi case. 4574 // If the index is non-smi trigger the non-smi case.
4624 STATIC_ASSERT(kSmiTag == 0); 4575 STATIC_ASSERT(kSmiTag == 0);
4625 __ test(index_, Immediate(kSmiTagMask)); 4576 __ JumpIfNotSmi(index_, &index_not_smi_);
4626 __ j(not_zero, &index_not_smi_);
4627 4577
4628 // Put smi-tagged index into scratch register. 4578 // Put smi-tagged index into scratch register.
4629 __ mov(scratch_, index_); 4579 __ mov(scratch_, index_);
4630 __ bind(&got_smi_index_); 4580 __ bind(&got_smi_index_);
4631 4581
4632 // Check for index out of range. 4582 // Check for index out of range.
4633 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset)); 4583 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset));
4634 __ j(above_equal, index_out_of_range_); 4584 __ j(above_equal, index_out_of_range_);
4635 4585
4636 // We need special handling for non-flat strings. 4586 // We need special handling for non-flat strings.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
4714 __ mov(scratch_, eax); 4664 __ mov(scratch_, eax);
4715 } 4665 }
4716 __ pop(index_); 4666 __ pop(index_);
4717 __ pop(object_); 4667 __ pop(object_);
4718 // Reload the instance type. 4668 // Reload the instance type.
4719 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4669 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4720 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4670 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4721 call_helper.AfterCall(masm); 4671 call_helper.AfterCall(masm);
4722 // If index is still not a smi, it must be out of range. 4672 // If index is still not a smi, it must be out of range.
4723 STATIC_ASSERT(kSmiTag == 0); 4673 STATIC_ASSERT(kSmiTag == 0);
4724 __ test(scratch_, Immediate(kSmiTagMask)); 4674 __ JumpIfNotSmi(scratch_, index_out_of_range_);
4725 __ j(not_zero, index_out_of_range_);
4726 // Otherwise, return to the fast path. 4675 // Otherwise, return to the fast path.
4727 __ jmp(&got_smi_index_); 4676 __ jmp(&got_smi_index_);
4728 4677
4729 // Call runtime. We get here when the receiver is a string and the 4678 // Call runtime. We get here when the receiver is a string and the
4730 // index is a number, but the code of getting the actual character 4679 // index is a number, but the code of getting the actual character
4731 // is too complex (e.g., when the string needs to be flattened). 4680 // is too complex (e.g., when the string needs to be flattened).
4732 __ bind(&call_runtime_); 4681 __ bind(&call_runtime_);
4733 call_helper.BeforeCall(masm); 4682 call_helper.BeforeCall(masm);
4734 __ push(object_); 4683 __ push(object_);
4735 __ push(index_); 4684 __ push(index_);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4809 void StringAddStub::Generate(MacroAssembler* masm) { 4758 void StringAddStub::Generate(MacroAssembler* masm) {
4810 Label string_add_runtime, call_builtin; 4759 Label string_add_runtime, call_builtin;
4811 Builtins::JavaScript builtin_id = Builtins::ADD; 4760 Builtins::JavaScript builtin_id = Builtins::ADD;
4812 4761
4813 // Load the two arguments. 4762 // Load the two arguments.
4814 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument. 4763 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument.
4815 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument. 4764 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
4816 4765
4817 // Make sure that both arguments are strings if not known in advance. 4766 // Make sure that both arguments are strings if not known in advance.
4818 if (flags_ == NO_STRING_ADD_FLAGS) { 4767 if (flags_ == NO_STRING_ADD_FLAGS) {
4819 __ test(eax, Immediate(kSmiTagMask)); 4768 __ JumpIfSmi(eax, &string_add_runtime);
4820 __ j(zero, &string_add_runtime);
4821 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ebx); 4769 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ebx);
4822 __ j(above_equal, &string_add_runtime); 4770 __ j(above_equal, &string_add_runtime);
4823 4771
4824 // First argument is a a string, test second. 4772 // First argument is a a string, test second.
4825 __ test(edx, Immediate(kSmiTagMask)); 4773 __ JumpIfSmi(edx, &string_add_runtime);
4826 __ j(zero, &string_add_runtime);
4827 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ebx); 4774 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ebx);
4828 __ j(above_equal, &string_add_runtime); 4775 __ j(above_equal, &string_add_runtime);
4829 } else { 4776 } else {
4830 // Here at least one of the arguments is definitely a string. 4777 // Here at least one of the arguments is definitely a string.
4831 // We convert the one that is not known to be a string. 4778 // We convert the one that is not known to be a string.
4832 if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) { 4779 if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) {
4833 ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0); 4780 ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0);
4834 GenerateConvertArgument(masm, 2 * kPointerSize, eax, ebx, ecx, edi, 4781 GenerateConvertArgument(masm, 2 * kPointerSize, eax, ebx, ecx, edi,
4835 &call_builtin); 4782 &call_builtin);
4836 builtin_id = Builtins::STRING_ADD_RIGHT; 4783 builtin_id = Builtins::STRING_ADD_RIGHT;
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
5084 5031
5085 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm, 5032 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
5086 int stack_offset, 5033 int stack_offset,
5087 Register arg, 5034 Register arg,
5088 Register scratch1, 5035 Register scratch1,
5089 Register scratch2, 5036 Register scratch2,
5090 Register scratch3, 5037 Register scratch3,
5091 Label* slow) { 5038 Label* slow) {
5092 // First check if the argument is already a string. 5039 // First check if the argument is already a string.
5093 Label not_string, done; 5040 Label not_string, done;
5094 __ test(arg, Immediate(kSmiTagMask)); 5041 __ JumpIfSmi(arg, &not_string);
5095 __ j(zero, &not_string);
5096 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1); 5042 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1);
5097 __ j(below, &done); 5043 __ j(below, &done);
5098 5044
5099 // Check the number to string cache. 5045 // Check the number to string cache.
5100 Label not_cached; 5046 Label not_cached;
5101 __ bind(&not_string); 5047 __ bind(&not_string);
5102 // Puts the cached result into scratch1. 5048 // Puts the cached result into scratch1.
5103 NumberToStringStub::GenerateLookupNumberStringCache(masm, 5049 NumberToStringStub::GenerateLookupNumberStringCache(masm,
5104 arg, 5050 arg,
5105 scratch1, 5051 scratch1,
5106 scratch2, 5052 scratch2,
5107 scratch3, 5053 scratch3,
5108 false, 5054 false,
5109 &not_cached); 5055 &not_cached);
5110 __ mov(arg, scratch1); 5056 __ mov(arg, scratch1);
5111 __ mov(Operand(esp, stack_offset), arg); 5057 __ mov(Operand(esp, stack_offset), arg);
5112 __ jmp(&done); 5058 __ jmp(&done);
5113 5059
5114 // Check if the argument is a safe string wrapper. 5060 // Check if the argument is a safe string wrapper.
5115 __ bind(&not_cached); 5061 __ bind(&not_cached);
5116 __ test(arg, Immediate(kSmiTagMask)); 5062 __ JumpIfSmi(arg, slow);
5117 __ j(zero, slow);
5118 __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1. 5063 __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1.
5119 __ j(not_equal, slow); 5064 __ j(not_equal, slow);
5120 __ test_b(FieldOperand(scratch1, Map::kBitField2Offset), 5065 __ test_b(FieldOperand(scratch1, Map::kBitField2Offset),
5121 1 << Map::kStringWrapperSafeForDefaultValueOf); 5066 1 << Map::kStringWrapperSafeForDefaultValueOf);
5122 __ j(zero, slow); 5067 __ j(zero, slow);
5123 __ mov(arg, FieldOperand(arg, JSValue::kValueOffset)); 5068 __ mov(arg, FieldOperand(arg, JSValue::kValueOffset));
5124 __ mov(Operand(esp, stack_offset), arg); 5069 __ mov(Operand(esp, stack_offset), arg);
5125 5070
5126 __ bind(&done); 5071 __ bind(&done);
5127 } 5072 }
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
5401 5346
5402 // Stack frame on entry. 5347 // Stack frame on entry.
5403 // esp[0]: return address 5348 // esp[0]: return address
5404 // esp[4]: to 5349 // esp[4]: to
5405 // esp[8]: from 5350 // esp[8]: from
5406 // esp[12]: string 5351 // esp[12]: string
5407 5352
5408 // Make sure first argument is a string. 5353 // Make sure first argument is a string.
5409 __ mov(eax, Operand(esp, 3 * kPointerSize)); 5354 __ mov(eax, Operand(esp, 3 * kPointerSize));
5410 STATIC_ASSERT(kSmiTag == 0); 5355 STATIC_ASSERT(kSmiTag == 0);
5411 __ test(eax, Immediate(kSmiTagMask)); 5356 __ JumpIfSmi(eax, &runtime);
5412 __ j(zero, &runtime);
5413 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); 5357 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
5414 __ j(NegateCondition(is_string), &runtime); 5358 __ j(NegateCondition(is_string), &runtime);
5415 5359
5416 // eax: string 5360 // eax: string
5417 // ebx: instance type 5361 // ebx: instance type
5418 5362
5419 // Calculate length of sub string using the smi values. 5363 // Calculate length of sub string using the smi values.
5420 Label result_longer_than_two; 5364 Label result_longer_than_two;
5421 __ mov(ecx, Operand(esp, 1 * kPointerSize)); // To index. 5365 __ mov(ecx, Operand(esp, 1 * kPointerSize)); // To index.
5422 __ test(ecx, Immediate(kSmiTagMask)); 5366 __ JumpIfNotSmi(ecx, &runtime);
5423 __ j(not_zero, &runtime);
5424 __ mov(edx, Operand(esp, 2 * kPointerSize)); // From index. 5367 __ mov(edx, Operand(esp, 2 * kPointerSize)); // From index.
5425 __ test(edx, Immediate(kSmiTagMask)); 5368 __ JumpIfNotSmi(edx, &runtime);
5426 __ j(not_zero, &runtime);
5427 __ sub(ecx, Operand(edx)); 5369 __ sub(ecx, Operand(edx));
5428 __ cmp(ecx, FieldOperand(eax, String::kLengthOffset)); 5370 __ cmp(ecx, FieldOperand(eax, String::kLengthOffset));
5429 Label return_eax; 5371 Label return_eax;
5430 __ j(equal, &return_eax); 5372 __ j(equal, &return_eax);
5431 // Special handling of sub-strings of length 1 and 2. One character strings 5373 // Special handling of sub-strings of length 1 and 2. One character strings
5432 // are handled in the runtime system (looked up in the single character 5374 // are handled in the runtime system (looked up in the single character
5433 // cache). Two character strings are looked for in the symbol cache. 5375 // cache). Two character strings are looked for in the symbol cache.
5434 __ SmiUntag(ecx); // Result length is no longer smi. 5376 __ SmiUntag(ecx); // Result length is no longer smi.
5435 __ cmp(ecx, 2); 5377 __ cmp(ecx, 2);
5436 __ j(greater, &result_longer_than_two); 5378 __ j(greater, &result_longer_than_two);
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
5708 __ bind(&runtime); 5650 __ bind(&runtime);
5709 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 5651 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
5710 } 5652 }
5711 5653
5712 5654
5713 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { 5655 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
5714 ASSERT(state_ == CompareIC::SMIS); 5656 ASSERT(state_ == CompareIC::SMIS);
5715 Label miss; 5657 Label miss;
5716 __ mov(ecx, Operand(edx)); 5658 __ mov(ecx, Operand(edx));
5717 __ or_(ecx, Operand(eax)); 5659 __ or_(ecx, Operand(eax));
5718 __ test(ecx, Immediate(kSmiTagMask)); 5660 __ JumpIfNotSmi(ecx, &miss, Label::kNear);
5719 __ j(not_zero, &miss, Label::kNear);
5720 5661
5721 if (GetCondition() == equal) { 5662 if (GetCondition() == equal) {
5722 // For equality we do not care about the sign of the result. 5663 // For equality we do not care about the sign of the result.
5723 __ sub(eax, Operand(edx)); 5664 __ sub(eax, Operand(edx));
5724 } else { 5665 } else {
5725 Label done; 5666 Label done;
5726 __ sub(edx, Operand(eax)); 5667 __ sub(edx, Operand(eax));
5727 __ j(no_overflow, &done, Label::kNear); 5668 __ j(no_overflow, &done, Label::kNear);
5728 // Correct sign of result in case of overflow. 5669 // Correct sign of result in case of overflow.
5729 __ not_(edx); 5670 __ not_(edx);
5730 __ bind(&done); 5671 __ bind(&done);
5731 __ mov(eax, edx); 5672 __ mov(eax, edx);
5732 } 5673 }
5733 __ ret(0); 5674 __ ret(0);
5734 5675
5735 __ bind(&miss); 5676 __ bind(&miss);
5736 GenerateMiss(masm); 5677 GenerateMiss(masm);
5737 } 5678 }
5738 5679
5739 5680
5740 void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) { 5681 void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) {
5741 ASSERT(state_ == CompareIC::HEAP_NUMBERS); 5682 ASSERT(state_ == CompareIC::HEAP_NUMBERS);
5742 5683
5743 Label generic_stub; 5684 Label generic_stub;
5744 Label unordered; 5685 Label unordered;
5745 Label miss; 5686 Label miss;
5746 __ mov(ecx, Operand(edx)); 5687 __ mov(ecx, Operand(edx));
5747 __ and_(ecx, Operand(eax)); 5688 __ and_(ecx, Operand(eax));
5748 __ test(ecx, Immediate(kSmiTagMask)); 5689 __ JumpIfSmi(ecx, &generic_stub, Label::kNear);
5749 __ j(zero, &generic_stub, Label::kNear);
5750 5690
5751 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); 5691 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx);
5752 __ j(not_equal, &miss, Label::kNear); 5692 __ j(not_equal, &miss, Label::kNear);
5753 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx); 5693 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx);
5754 __ j(not_equal, &miss, Label::kNear); 5694 __ j(not_equal, &miss, Label::kNear);
5755 5695
5756 // Inlining the double comparison and falling back to the general compare 5696 // Inlining the double comparison and falling back to the general compare
5757 // stub if NaN is involved or SS2 or CMOV is unsupported. 5697 // stub if NaN is involved or SS2 or CMOV is unsupported.
5758 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) { 5698 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) {
5759 CpuFeatures::Scope scope1(SSE2); 5699 CpuFeatures::Scope scope1(SSE2);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5798 Register left = edx; 5738 Register left = edx;
5799 Register right = eax; 5739 Register right = eax;
5800 Register tmp1 = ecx; 5740 Register tmp1 = ecx;
5801 Register tmp2 = ebx; 5741 Register tmp2 = ebx;
5802 5742
5803 // Check that both operands are heap objects. 5743 // Check that both operands are heap objects.
5804 Label miss; 5744 Label miss;
5805 __ mov(tmp1, Operand(left)); 5745 __ mov(tmp1, Operand(left));
5806 STATIC_ASSERT(kSmiTag == 0); 5746 STATIC_ASSERT(kSmiTag == 0);
5807 __ and_(tmp1, Operand(right)); 5747 __ and_(tmp1, Operand(right));
5808 __ test(tmp1, Immediate(kSmiTagMask)); 5748 __ JumpIfSmi(tmp1, &miss, Label::kNear);
5809 __ j(zero, &miss, Label::kNear);
5810 5749
5811 // Check that both operands are symbols. 5750 // Check that both operands are symbols.
5812 __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset)); 5751 __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset));
5813 __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset)); 5752 __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset));
5814 __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); 5753 __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset));
5815 __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); 5754 __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset));
5816 STATIC_ASSERT(kSymbolTag != 0); 5755 STATIC_ASSERT(kSymbolTag != 0);
5817 __ and_(tmp1, Operand(tmp2)); 5756 __ and_(tmp1, Operand(tmp2));
5818 __ test(tmp1, Immediate(kIsSymbolMask)); 5757 __ test(tmp1, Immediate(kIsSymbolMask));
5819 __ j(zero, &miss, Label::kNear); 5758 __ j(zero, &miss, Label::kNear);
(...skipping 25 matching lines...) Expand all
5845 Register left = edx; 5784 Register left = edx;
5846 Register right = eax; 5785 Register right = eax;
5847 Register tmp1 = ecx; 5786 Register tmp1 = ecx;
5848 Register tmp2 = ebx; 5787 Register tmp2 = ebx;
5849 Register tmp3 = edi; 5788 Register tmp3 = edi;
5850 5789
5851 // Check that both operands are heap objects. 5790 // Check that both operands are heap objects.
5852 __ mov(tmp1, Operand(left)); 5791 __ mov(tmp1, Operand(left));
5853 STATIC_ASSERT(kSmiTag == 0); 5792 STATIC_ASSERT(kSmiTag == 0);
5854 __ and_(tmp1, Operand(right)); 5793 __ and_(tmp1, Operand(right));
5855 __ test(tmp1, Immediate(kSmiTagMask)); 5794 __ JumpIfSmi(tmp1, &miss);
5856 __ j(zero, &miss);
5857 5795
5858 // Check that both operands are strings. This leaves the instance 5796 // Check that both operands are strings. This leaves the instance
5859 // types loaded in tmp1 and tmp2. 5797 // types loaded in tmp1 and tmp2.
5860 __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset)); 5798 __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset));
5861 __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset)); 5799 __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset));
5862 __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); 5800 __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset));
5863 __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); 5801 __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset));
5864 __ mov(tmp3, tmp1); 5802 __ mov(tmp3, tmp1);
5865 STATIC_ASSERT(kNotStringTag != 0); 5803 STATIC_ASSERT(kNotStringTag != 0);
5866 __ or_(tmp3, Operand(tmp2)); 5804 __ or_(tmp3, Operand(tmp2));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
5911 __ bind(&miss); 5849 __ bind(&miss);
5912 GenerateMiss(masm); 5850 GenerateMiss(masm);
5913 } 5851 }
5914 5852
5915 5853
5916 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { 5854 void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
5917 ASSERT(state_ == CompareIC::OBJECTS); 5855 ASSERT(state_ == CompareIC::OBJECTS);
5918 Label miss; 5856 Label miss;
5919 __ mov(ecx, Operand(edx)); 5857 __ mov(ecx, Operand(edx));
5920 __ and_(ecx, Operand(eax)); 5858 __ and_(ecx, Operand(eax));
5921 __ test(ecx, Immediate(kSmiTagMask)); 5859 __ JumpIfSmi(ecx, &miss, Label::kNear);
5922 __ j(zero, &miss, Label::kNear);
5923 5860
5924 __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx); 5861 __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx);
5925 __ j(not_equal, &miss, Label::kNear); 5862 __ j(not_equal, &miss, Label::kNear);
5926 __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx); 5863 __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx);
5927 __ j(not_equal, &miss, Label::kNear); 5864 __ j(not_equal, &miss, Label::kNear);
5928 5865
5929 ASSERT(GetCondition() == equal); 5866 ASSERT(GetCondition() == equal);
5930 __ sub(eax, Operand(edx)); 5867 __ sub(eax, Operand(edx));
5931 __ ret(0); 5868 __ ret(0);
5932 5869
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
6176 __ Drop(1); 6113 __ Drop(1);
6177 __ ret(2 * kPointerSize); 6114 __ ret(2 * kPointerSize);
6178 } 6115 }
6179 6116
6180 6117
6181 #undef __ 6118 #undef __
6182 6119
6183 } } // namespace v8::internal 6120 } } // namespace v8::internal
6184 6121
6185 #endif // V8_TARGET_ARCH_IA32 6122 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698