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

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

Powered by Google App Engine
This is Rietveld 408576698