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

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

Issue 17276002: Refactor lithium codegen to not pass around block_ids (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1843 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 1854
1855 1855
1856 int LCodeGen::GetNextEmittedBlock() const { 1856 int LCodeGen::GetNextEmittedBlock() const {
1857 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 1857 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
1858 if (!chunk_->GetLabel(i)->HasReplacement()) return i; 1858 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
1859 } 1859 }
1860 return -1; 1860 return -1;
1861 } 1861 }
1862 1862
1863 1863
1864 void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { 1864 template<class InstrType>
1865 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
1866 int right_block = instr->FalseDestination(chunk_);
1867 int left_block = instr->TrueDestination(chunk_);
1868
1865 int next_block = GetNextEmittedBlock(); 1869 int next_block = GetNextEmittedBlock();
1866 right_block = chunk_->LookupDestination(right_block);
1867 left_block = chunk_->LookupDestination(left_block);
1868 1870
1869 if (right_block == left_block) { 1871 if (right_block == left_block) {
1870 EmitGoto(left_block); 1872 EmitGoto(left_block);
1871 } else if (left_block == next_block) { 1873 } else if (left_block == next_block) {
1872 __ j(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block)); 1874 __ j(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block));
1873 } else if (right_block == next_block) { 1875 } else if (right_block == next_block) {
1874 __ j(cc, chunk_->GetAssemblyLabel(left_block)); 1876 __ j(cc, chunk_->GetAssemblyLabel(left_block));
1875 } else { 1877 } else {
1876 __ j(cc, chunk_->GetAssemblyLabel(left_block)); 1878 __ j(cc, chunk_->GetAssemblyLabel(left_block));
1877 if (cc != always) { 1879 if (cc != always) {
1878 __ jmp(chunk_->GetAssemblyLabel(right_block)); 1880 __ jmp(chunk_->GetAssemblyLabel(right_block));
1879 } 1881 }
1880 } 1882 }
1881 } 1883 }
1882 1884
1883 1885
1884 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 1886 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
1885 __ int3(); 1887 __ int3();
1886 } 1888 }
1887 1889
1888 1890
1889 void LCodeGen::DoBranch(LBranch* instr) { 1891 void LCodeGen::DoBranch(LBranch* instr) {
1890 int true_block = chunk_->LookupDestination(instr->true_block_id());
1891 int false_block = chunk_->LookupDestination(instr->false_block_id());
1892
1893 Representation r = instr->hydrogen()->value()->representation(); 1892 Representation r = instr->hydrogen()->value()->representation();
1894 if (r.IsInteger32()) { 1893 if (r.IsInteger32()) {
1895 ASSERT(!info()->IsStub()); 1894 ASSERT(!info()->IsStub());
1896 Register reg = ToRegister(instr->value()); 1895 Register reg = ToRegister(instr->value());
1897 __ testl(reg, reg); 1896 __ testl(reg, reg);
1898 EmitBranch(true_block, false_block, not_zero); 1897 EmitBranch(instr, not_zero);
1899 } else if (r.IsSmi()) { 1898 } else if (r.IsSmi()) {
1900 ASSERT(!info()->IsStub()); 1899 ASSERT(!info()->IsStub());
1901 Register reg = ToRegister(instr->value()); 1900 Register reg = ToRegister(instr->value());
1902 __ testq(reg, reg); 1901 __ testq(reg, reg);
1903 EmitBranch(true_block, false_block, not_zero); 1902 EmitBranch(instr, not_zero);
1904 } else if (r.IsDouble()) { 1903 } else if (r.IsDouble()) {
1905 ASSERT(!info()->IsStub()); 1904 ASSERT(!info()->IsStub());
1906 XMMRegister reg = ToDoubleRegister(instr->value()); 1905 XMMRegister reg = ToDoubleRegister(instr->value());
1907 __ xorps(xmm0, xmm0); 1906 __ xorps(xmm0, xmm0);
1908 __ ucomisd(reg, xmm0); 1907 __ ucomisd(reg, xmm0);
1909 EmitBranch(true_block, false_block, not_equal); 1908 EmitBranch(instr, not_equal);
1910 } else { 1909 } else {
1911 ASSERT(r.IsTagged()); 1910 ASSERT(r.IsTagged());
1912 Register reg = ToRegister(instr->value()); 1911 Register reg = ToRegister(instr->value());
1913 HType type = instr->hydrogen()->value()->type(); 1912 HType type = instr->hydrogen()->value()->type();
1914 if (type.IsBoolean()) { 1913 if (type.IsBoolean()) {
1915 ASSERT(!info()->IsStub()); 1914 ASSERT(!info()->IsStub());
1916 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1915 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1917 EmitBranch(true_block, false_block, equal); 1916 EmitBranch(instr, equal);
1918 } else if (type.IsSmi()) { 1917 } else if (type.IsSmi()) {
1919 ASSERT(!info()->IsStub()); 1918 ASSERT(!info()->IsStub());
1920 __ SmiCompare(reg, Smi::FromInt(0)); 1919 __ SmiCompare(reg, Smi::FromInt(0));
1921 EmitBranch(true_block, false_block, not_equal); 1920 EmitBranch(instr, not_equal);
1922 } else { 1921 } else {
1923 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1924 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1925
1926 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 1922 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
1927 // Avoid deopts in the case where we've never executed this path before. 1923 // Avoid deopts in the case where we've never executed this path before.
1928 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 1924 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
1929 1925
1930 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 1926 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
1931 // undefined -> false. 1927 // undefined -> false.
1932 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); 1928 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1933 __ j(equal, false_label); 1929 __ j(equal, instr->FalseLabel(chunk_));
1934 } 1930 }
1935 if (expected.Contains(ToBooleanStub::BOOLEAN)) { 1931 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1936 // true -> true. 1932 // true -> true.
1937 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1933 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1938 __ j(equal, true_label); 1934 __ j(equal, instr->TrueLabel(chunk_));
1939 // false -> false. 1935 // false -> false.
1940 __ CompareRoot(reg, Heap::kFalseValueRootIndex); 1936 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1941 __ j(equal, false_label); 1937 __ j(equal, instr->FalseLabel(chunk_));
1942 } 1938 }
1943 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 1939 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
1944 // 'null' -> false. 1940 // 'null' -> false.
1945 __ CompareRoot(reg, Heap::kNullValueRootIndex); 1941 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1946 __ j(equal, false_label); 1942 __ j(equal, instr->FalseLabel(chunk_));
1947 } 1943 }
1948 1944
1949 if (expected.Contains(ToBooleanStub::SMI)) { 1945 if (expected.Contains(ToBooleanStub::SMI)) {
1950 // Smis: 0 -> false, all other -> true. 1946 // Smis: 0 -> false, all other -> true.
1951 __ Cmp(reg, Smi::FromInt(0)); 1947 __ Cmp(reg, Smi::FromInt(0));
1952 __ j(equal, false_label); 1948 __ j(equal, instr->FalseLabel(chunk_));
1953 __ JumpIfSmi(reg, true_label); 1949 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
1954 } else if (expected.NeedsMap()) { 1950 } else if (expected.NeedsMap()) {
1955 // If we need a map later and have a Smi -> deopt. 1951 // If we need a map later and have a Smi -> deopt.
1956 __ testb(reg, Immediate(kSmiTagMask)); 1952 __ testb(reg, Immediate(kSmiTagMask));
1957 DeoptimizeIf(zero, instr->environment()); 1953 DeoptimizeIf(zero, instr->environment());
1958 } 1954 }
1959 1955
1960 const Register map = kScratchRegister; 1956 const Register map = kScratchRegister;
1961 if (expected.NeedsMap()) { 1957 if (expected.NeedsMap()) {
1962 __ movq(map, FieldOperand(reg, HeapObject::kMapOffset)); 1958 __ movq(map, FieldOperand(reg, HeapObject::kMapOffset));
1963 1959
1964 if (expected.CanBeUndetectable()) { 1960 if (expected.CanBeUndetectable()) {
1965 // Undetectable -> false. 1961 // Undetectable -> false.
1966 __ testb(FieldOperand(map, Map::kBitFieldOffset), 1962 __ testb(FieldOperand(map, Map::kBitFieldOffset),
1967 Immediate(1 << Map::kIsUndetectable)); 1963 Immediate(1 << Map::kIsUndetectable));
1968 __ j(not_zero, false_label); 1964 __ j(not_zero, instr->FalseLabel(chunk_));
1969 } 1965 }
1970 } 1966 }
1971 1967
1972 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 1968 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
1973 // spec object -> true. 1969 // spec object -> true.
1974 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 1970 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
1975 __ j(above_equal, true_label); 1971 __ j(above_equal, instr->TrueLabel(chunk_));
1976 } 1972 }
1977 1973
1978 if (expected.Contains(ToBooleanStub::STRING)) { 1974 if (expected.Contains(ToBooleanStub::STRING)) {
1979 // String value -> false iff empty. 1975 // String value -> false iff empty.
1980 Label not_string; 1976 Label not_string;
1981 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 1977 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
1982 __ j(above_equal, &not_string, Label::kNear); 1978 __ j(above_equal, &not_string, Label::kNear);
1983 __ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 1979 __ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0));
1984 __ j(not_zero, true_label); 1980 __ j(not_zero, instr->TrueLabel(chunk_));
1985 __ jmp(false_label); 1981 __ jmp(instr->FalseLabel(chunk_));
1986 __ bind(&not_string); 1982 __ bind(&not_string);
1987 } 1983 }
1988 1984
1989 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 1985 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
1990 // heap number -> false iff +0, -0, or NaN. 1986 // heap number -> false iff +0, -0, or NaN.
1991 Label not_heap_number; 1987 Label not_heap_number;
1992 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 1988 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1993 __ j(not_equal, &not_heap_number, Label::kNear); 1989 __ j(not_equal, &not_heap_number, Label::kNear);
1994 __ xorps(xmm0, xmm0); 1990 __ xorps(xmm0, xmm0);
1995 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 1991 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset));
1996 __ j(zero, false_label); 1992 __ j(zero, instr->FalseLabel(chunk_));
1997 __ jmp(true_label); 1993 __ jmp(instr->TrueLabel(chunk_));
1998 __ bind(&not_heap_number); 1994 __ bind(&not_heap_number);
1999 } 1995 }
2000 1996
2001 // We've seen something for the first time -> deopt. 1997 // We've seen something for the first time -> deopt.
2002 DeoptimizeIf(no_condition, instr->environment()); 1998 DeoptimizeIf(no_condition, instr->environment());
2003 } 1999 }
2004 } 2000 }
2005 } 2001 }
2006 2002
2007 2003
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2041 default: 2037 default:
2042 UNREACHABLE(); 2038 UNREACHABLE();
2043 } 2039 }
2044 return cond; 2040 return cond;
2045 } 2041 }
2046 2042
2047 2043
2048 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 2044 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
2049 LOperand* left = instr->left(); 2045 LOperand* left = instr->left();
2050 LOperand* right = instr->right(); 2046 LOperand* right = instr->right();
2051 int false_block = chunk_->LookupDestination(instr->false_block_id());
2052 int true_block = chunk_->LookupDestination(instr->true_block_id());
2053 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 2047 Condition cc = TokenToCondition(instr->op(), instr->is_double());
2054 2048
2055 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2049 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2056 // We can statically evaluate the comparison. 2050 // We can statically evaluate the comparison.
2057 double left_val = ToDouble(LConstantOperand::cast(left)); 2051 double left_val = ToDouble(LConstantOperand::cast(left));
2058 double right_val = ToDouble(LConstantOperand::cast(right)); 2052 double right_val = ToDouble(LConstantOperand::cast(right));
2059 int next_block = 2053 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2060 EvalComparison(instr->op(), left_val, right_val) ? true_block 2054 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2061 : false_block;
2062 EmitGoto(next_block); 2055 EmitGoto(next_block);
2063 } else { 2056 } else {
2064 if (instr->is_double()) { 2057 if (instr->is_double()) {
2065 // Don't base result on EFLAGS when a NaN is involved. Instead 2058 // Don't base result on EFLAGS when a NaN is involved. Instead
2066 // jump to the false block. 2059 // jump to the false block.
2067 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 2060 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
2068 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); 2061 __ j(parity_even, instr->FalseLabel(chunk_));
2069 } else { 2062 } else {
2070 int32_t value; 2063 int32_t value;
2071 if (right->IsConstantOperand()) { 2064 if (right->IsConstantOperand()) {
2072 value = ToInteger32(LConstantOperand::cast(right)); 2065 value = ToInteger32(LConstantOperand::cast(right));
2073 if (instr->hydrogen_value()->representation().IsSmi()) { 2066 if (instr->hydrogen_value()->representation().IsSmi()) {
2074 __ Cmp(ToRegister(left), Smi::FromInt(value)); 2067 __ Cmp(ToRegister(left), Smi::FromInt(value));
2075 } else { 2068 } else {
2076 __ cmpl(ToRegister(left), Immediate(value)); 2069 __ cmpl(ToRegister(left), Immediate(value));
2077 } 2070 }
2078 } else if (left->IsConstantOperand()) { 2071 } else if (left->IsConstantOperand()) {
(...skipping 18 matching lines...) Expand all
2097 __ cmpq(ToRegister(left), ToOperand(right)); 2090 __ cmpq(ToRegister(left), ToOperand(right));
2098 } 2091 }
2099 } else { 2092 } else {
2100 if (right->IsRegister()) { 2093 if (right->IsRegister()) {
2101 __ cmpl(ToRegister(left), ToRegister(right)); 2094 __ cmpl(ToRegister(left), ToRegister(right));
2102 } else { 2095 } else {
2103 __ cmpl(ToRegister(left), ToOperand(right)); 2096 __ cmpl(ToRegister(left), ToOperand(right));
2104 } 2097 }
2105 } 2098 }
2106 } 2099 }
2107 EmitBranch(true_block, false_block, cc); 2100 EmitBranch(instr, cc);
2108 } 2101 }
2109 } 2102 }
2110 2103
2111 2104
2112 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2105 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2113 Register left = ToRegister(instr->left()); 2106 Register left = ToRegister(instr->left());
2114 int false_block = chunk_->LookupDestination(instr->false_block_id());
2115 int true_block = chunk_->LookupDestination(instr->true_block_id());
2116 2107
2117 if (instr->right()->IsConstantOperand()) { 2108 if (instr->right()->IsConstantOperand()) {
2118 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); 2109 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2119 __ CmpObject(left, right); 2110 __ CmpObject(left, right);
2120 } else { 2111 } else {
2121 Register right = ToRegister(instr->right()); 2112 Register right = ToRegister(instr->right());
2122 __ cmpq(left, right); 2113 __ cmpq(left, right);
2123 } 2114 }
2124 EmitBranch(true_block, false_block, equal); 2115 EmitBranch(instr, equal);
2125 } 2116 }
2126 2117
2127 2118
2128 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 2119 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
2129 Register left = ToRegister(instr->left()); 2120 Register left = ToRegister(instr->left());
2130 int true_block = chunk_->LookupDestination(instr->true_block_id());
2131 int false_block = chunk_->LookupDestination(instr->false_block_id());
2132 2121
2133 __ cmpq(left, Immediate(instr->hydrogen()->right())); 2122 __ cmpq(left, Immediate(instr->hydrogen()->right()));
2134 EmitBranch(true_block, false_block, equal); 2123 EmitBranch(instr, equal);
2135 } 2124 }
2136 2125
2137 2126
2138 Condition LCodeGen::EmitIsObject(Register input, 2127 Condition LCodeGen::EmitIsObject(Register input,
2139 Label* is_not_object, 2128 Label* is_not_object,
2140 Label* is_object) { 2129 Label* is_object) {
2141 ASSERT(!input.is(kScratchRegister)); 2130 ASSERT(!input.is(kScratchRegister));
2142 2131
2143 __ JumpIfSmi(input, is_not_object); 2132 __ JumpIfSmi(input, is_not_object);
2144 2133
(...skipping 11 matching lines...) Expand all
2156 __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2145 __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
2157 __ j(below, is_not_object); 2146 __ j(below, is_not_object);
2158 __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2147 __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
2159 return below_equal; 2148 return below_equal;
2160 } 2149 }
2161 2150
2162 2151
2163 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 2152 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2164 Register reg = ToRegister(instr->value()); 2153 Register reg = ToRegister(instr->value());
2165 2154
2166 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2155 Condition true_cond = EmitIsObject(
2167 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2156 reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2168 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2169 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2170 2157
2171 Condition true_cond = EmitIsObject(reg, false_label, true_label); 2158 EmitBranch(instr, true_cond);
2172
2173 EmitBranch(true_block, false_block, true_cond);
2174 } 2159 }
2175 2160
2176 2161
2177 Condition LCodeGen::EmitIsString(Register input, 2162 Condition LCodeGen::EmitIsString(Register input,
2178 Register temp1, 2163 Register temp1,
2179 Label* is_not_string) { 2164 Label* is_not_string) {
2180 __ JumpIfSmi(input, is_not_string); 2165 __ JumpIfSmi(input, is_not_string);
2181 Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 2166 Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
2182 2167
2183 return cond; 2168 return cond;
2184 } 2169 }
2185 2170
2186 2171
2187 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2172 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2188 Register reg = ToRegister(instr->value()); 2173 Register reg = ToRegister(instr->value());
2189 Register temp = ToRegister(instr->temp()); 2174 Register temp = ToRegister(instr->temp());
2190 2175
2191 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2176 Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_));
2192 int false_block = chunk_->LookupDestination(instr->false_block_id());
2193 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2194 2177
2195 Condition true_cond = EmitIsString(reg, temp, false_label); 2178 EmitBranch(instr, true_cond);
2196
2197 EmitBranch(true_block, false_block, true_cond);
2198 } 2179 }
2199 2180
2200 2181
2201 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2182 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2202 int true_block = chunk_->LookupDestination(instr->true_block_id());
2203 int false_block = chunk_->LookupDestination(instr->false_block_id());
2204
2205 Condition is_smi; 2183 Condition is_smi;
2206 if (instr->value()->IsRegister()) { 2184 if (instr->value()->IsRegister()) {
2207 Register input = ToRegister(instr->value()); 2185 Register input = ToRegister(instr->value());
2208 is_smi = masm()->CheckSmi(input); 2186 is_smi = masm()->CheckSmi(input);
2209 } else { 2187 } else {
2210 Operand input = ToOperand(instr->value()); 2188 Operand input = ToOperand(instr->value());
2211 is_smi = masm()->CheckSmi(input); 2189 is_smi = masm()->CheckSmi(input);
2212 } 2190 }
2213 EmitBranch(true_block, false_block, is_smi); 2191 EmitBranch(instr, is_smi);
2214 } 2192 }
2215 2193
2216 2194
2217 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2195 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2218 Register input = ToRegister(instr->value()); 2196 Register input = ToRegister(instr->value());
2219 Register temp = ToRegister(instr->temp()); 2197 Register temp = ToRegister(instr->temp());
2220 2198
2221 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2199 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2222 int false_block = chunk_->LookupDestination(instr->false_block_id());
2223
2224 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
2225 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); 2200 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
2226 __ testb(FieldOperand(temp, Map::kBitFieldOffset), 2201 __ testb(FieldOperand(temp, Map::kBitFieldOffset),
2227 Immediate(1 << Map::kIsUndetectable)); 2202 Immediate(1 << Map::kIsUndetectable));
2228 EmitBranch(true_block, false_block, not_zero); 2203 EmitBranch(instr, not_zero);
2229 } 2204 }
2230 2205
2231 2206
2232 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 2207 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2233 Token::Value op = instr->op(); 2208 Token::Value op = instr->op();
2234 int true_block = chunk_->LookupDestination(instr->true_block_id());
2235 int false_block = chunk_->LookupDestination(instr->false_block_id());
2236 2209
2237 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2210 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2238 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2211 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2239 2212
2240 Condition condition = TokenToCondition(op, false); 2213 Condition condition = TokenToCondition(op, false);
2241 __ testq(rax, rax); 2214 __ testq(rax, rax);
2242 2215
2243 EmitBranch(true_block, false_block, condition); 2216 EmitBranch(instr, condition);
2244 } 2217 }
2245 2218
2246 2219
2247 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 2220 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2248 InstanceType from = instr->from(); 2221 InstanceType from = instr->from();
2249 InstanceType to = instr->to(); 2222 InstanceType to = instr->to();
2250 if (from == FIRST_TYPE) return to; 2223 if (from == FIRST_TYPE) return to;
2251 ASSERT(from == to || to == LAST_TYPE); 2224 ASSERT(from == to || to == LAST_TYPE);
2252 return from; 2225 return from;
2253 } 2226 }
2254 2227
2255 2228
2256 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 2229 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2257 InstanceType from = instr->from(); 2230 InstanceType from = instr->from();
2258 InstanceType to = instr->to(); 2231 InstanceType to = instr->to();
2259 if (from == to) return equal; 2232 if (from == to) return equal;
2260 if (to == LAST_TYPE) return above_equal; 2233 if (to == LAST_TYPE) return above_equal;
2261 if (from == FIRST_TYPE) return below_equal; 2234 if (from == FIRST_TYPE) return below_equal;
2262 UNREACHABLE(); 2235 UNREACHABLE();
2263 return equal; 2236 return equal;
2264 } 2237 }
2265 2238
2266 2239
2267 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2240 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2268 Register input = ToRegister(instr->value()); 2241 Register input = ToRegister(instr->value());
2269 2242
2270 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2243 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2271 int false_block = chunk_->LookupDestination(instr->false_block_id());
2272
2273 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2274
2275 __ JumpIfSmi(input, false_label);
2276 2244
2277 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister); 2245 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
2278 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 2246 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2279 } 2247 }
2280 2248
2281 2249
2282 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2250 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2283 Register input = ToRegister(instr->value()); 2251 Register input = ToRegister(instr->value());
2284 Register result = ToRegister(instr->result()); 2252 Register result = ToRegister(instr->result());
2285 2253
2286 __ AssertString(input); 2254 __ AssertString(input);
2287 2255
2288 __ movl(result, FieldOperand(input, String::kHashFieldOffset)); 2256 __ movl(result, FieldOperand(input, String::kHashFieldOffset));
2289 ASSERT(String::kHashShift >= kSmiTagSize); 2257 ASSERT(String::kHashShift >= kSmiTagSize);
2290 __ IndexFromHash(result, result); 2258 __ IndexFromHash(result, result);
2291 } 2259 }
2292 2260
2293 2261
2294 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2262 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2295 LHasCachedArrayIndexAndBranch* instr) { 2263 LHasCachedArrayIndexAndBranch* instr) {
2296 Register input = ToRegister(instr->value()); 2264 Register input = ToRegister(instr->value());
2297 2265
2298 int true_block = chunk_->LookupDestination(instr->true_block_id());
2299 int false_block = chunk_->LookupDestination(instr->false_block_id());
2300
2301 __ testl(FieldOperand(input, String::kHashFieldOffset), 2266 __ testl(FieldOperand(input, String::kHashFieldOffset),
2302 Immediate(String::kContainsCachedArrayIndexMask)); 2267 Immediate(String::kContainsCachedArrayIndexMask));
2303 EmitBranch(true_block, false_block, equal); 2268 EmitBranch(instr, equal);
2304 } 2269 }
2305 2270
2306 2271
2307 // Branches to a label or falls through with the answer in the z flag. 2272 // Branches to a label or falls through with the answer in the z flag.
2308 // Trashes the temp register. 2273 // Trashes the temp register.
2309 void LCodeGen::EmitClassOfTest(Label* is_true, 2274 void LCodeGen::EmitClassOfTest(Label* is_true,
2310 Label* is_false, 2275 Label* is_false,
2311 Handle<String> class_name, 2276 Handle<String> class_name,
2312 Register input, 2277 Register input,
2313 Register temp, 2278 Register temp,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2371 // End with the answer in the z flag. 2336 // End with the answer in the z flag.
2372 } 2337 }
2373 2338
2374 2339
2375 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2340 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2376 Register input = ToRegister(instr->value()); 2341 Register input = ToRegister(instr->value());
2377 Register temp = ToRegister(instr->temp()); 2342 Register temp = ToRegister(instr->temp());
2378 Register temp2 = ToRegister(instr->temp2()); 2343 Register temp2 = ToRegister(instr->temp2());
2379 Handle<String> class_name = instr->hydrogen()->class_name(); 2344 Handle<String> class_name = instr->hydrogen()->class_name();
2380 2345
2381 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2346 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2382 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2347 class_name, input, temp, temp2);
2383 2348
2384 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2349 EmitBranch(instr, equal);
2385 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2386
2387 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2388
2389 EmitBranch(true_block, false_block, equal);
2390 } 2350 }
2391 2351
2392 2352
2393 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2353 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2394 Register reg = ToRegister(instr->value()); 2354 Register reg = ToRegister(instr->value());
2395 int true_block = instr->true_block_id();
2396 int false_block = instr->false_block_id();
2397 2355
2398 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 2356 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2399 EmitBranch(true_block, false_block, equal); 2357 EmitBranch(instr, equal);
2400 } 2358 }
2401 2359
2402 2360
2403 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2361 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2404 InstanceofStub stub(InstanceofStub::kNoFlags); 2362 InstanceofStub stub(InstanceofStub::kNoFlags);
2405 __ push(ToRegister(instr->left())); 2363 __ push(ToRegister(instr->left()));
2406 __ push(ToRegister(instr->right())); 2364 __ push(ToRegister(instr->right()));
2407 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2365 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2408 Label true_value, done; 2366 Label true_value, done;
2409 __ testq(rax, rax); 2367 __ testq(rax, rax);
(...skipping 2841 matching lines...) Expand 10 before | Expand all | Expand 10 after
5251 } else if (operand->IsRegister()) { 5209 } else if (operand->IsRegister()) {
5252 __ push(ToRegister(operand)); 5210 __ push(ToRegister(operand));
5253 } else { 5211 } else {
5254 __ push(ToOperand(operand)); 5212 __ push(ToOperand(operand));
5255 } 5213 }
5256 } 5214 }
5257 5215
5258 5216
5259 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5217 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5260 Register input = ToRegister(instr->value()); 5218 Register input = ToRegister(instr->value());
5261 int true_block = chunk_->LookupDestination(instr->true_block_id());
5262 int false_block = chunk_->LookupDestination(instr->false_block_id());
5263 Label* true_label = chunk_->GetAssemblyLabel(true_block);
5264 Label* false_label = chunk_->GetAssemblyLabel(false_block);
5265 5219
5266 Condition final_branch_condition = 5220 Condition final_branch_condition =
5267 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); 5221 EmitTypeofIs(instr->TrueLabel(chunk_),
5222 instr->FalseLabel(chunk_), input, instr->type_literal());
5268 if (final_branch_condition != no_condition) { 5223 if (final_branch_condition != no_condition) {
5269 EmitBranch(true_block, false_block, final_branch_condition); 5224 EmitBranch(instr, final_branch_condition);
5270 } 5225 }
5271 } 5226 }
5272 5227
5273 5228
5274 Condition LCodeGen::EmitTypeofIs(Label* true_label, 5229 Condition LCodeGen::EmitTypeofIs(Label* true_label,
5275 Label* false_label, 5230 Label* false_label,
5276 Register input, 5231 Register input,
5277 Handle<String> type_name) { 5232 Handle<String> type_name) {
5278 Condition final_branch_condition = no_condition; 5233 Condition final_branch_condition = no_condition;
5279 if (type_name->Equals(heap()->number_string())) { 5234 if (type_name->Equals(heap()->number_string())) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
5342 } else { 5297 } else {
5343 __ jmp(false_label); 5298 __ jmp(false_label);
5344 } 5299 }
5345 5300
5346 return final_branch_condition; 5301 return final_branch_condition;
5347 } 5302 }
5348 5303
5349 5304
5350 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5305 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5351 Register temp = ToRegister(instr->temp()); 5306 Register temp = ToRegister(instr->temp());
5352 int true_block = chunk_->LookupDestination(instr->true_block_id());
5353 int false_block = chunk_->LookupDestination(instr->false_block_id());
5354 5307
5355 EmitIsConstructCall(temp); 5308 EmitIsConstructCall(temp);
5356 EmitBranch(true_block, false_block, equal); 5309 EmitBranch(instr, equal);
5357 } 5310 }
5358 5311
5359 5312
5360 void LCodeGen::EmitIsConstructCall(Register temp) { 5313 void LCodeGen::EmitIsConstructCall(Register temp) {
5361 // Get the frame pointer for the calling frame. 5314 // Get the frame pointer for the calling frame.
5362 __ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 5315 __ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
5363 5316
5364 // Skip the arguments adaptor frame if it exists. 5317 // Skip the arguments adaptor frame if it exists.
5365 Label check_frame_marker; 5318 Label check_frame_marker;
5366 __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset), 5319 __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset),
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
5604 FixedArray::kHeaderSize - kPointerSize)); 5557 FixedArray::kHeaderSize - kPointerSize));
5605 __ bind(&done); 5558 __ bind(&done);
5606 } 5559 }
5607 5560
5608 5561
5609 #undef __ 5562 #undef __
5610 5563
5611 } } // namespace v8::internal 5564 } } // namespace v8::internal
5612 5565
5613 #endif // V8_TARGET_ARCH_X64 5566 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698