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

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

Issue 17504002: MIPS: Lithium codegen should 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
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-mips.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1952 matching lines...) Expand 10 before | Expand all | Expand 10 after
1963 } 1963 }
1964 1964
1965 1965
1966 int LCodeGen::GetNextEmittedBlock() const { 1966 int LCodeGen::GetNextEmittedBlock() const {
1967 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 1967 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
1968 if (!chunk_->GetLabel(i)->HasReplacement()) return i; 1968 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
1969 } 1969 }
1970 return -1; 1970 return -1;
1971 } 1971 }
1972 1972
1973 template<class InstrType>
1974 void LCodeGen::EmitBranch(InstrType instr,
1975 Condition cc, Register src1, const Operand& src2) {
1976 int right_block = instr->FalseDestination(chunk_);
1977 int left_block = instr->TrueDestination(chunk_);
1973 1978
1974 void LCodeGen::EmitBranch(int left_block, int right_block,
1975 Condition cc, Register src1, const Operand& src2) {
1976 int next_block = GetNextEmittedBlock(); 1979 int next_block = GetNextEmittedBlock();
1977 right_block = chunk_->LookupDestination(right_block);
1978 left_block = chunk_->LookupDestination(left_block);
1979 if (right_block == left_block) { 1980 if (right_block == left_block) {
1980 EmitGoto(left_block); 1981 EmitGoto(left_block);
1981 } else if (left_block == next_block) { 1982 } else if (left_block == next_block) {
1982 __ Branch(chunk_->GetAssemblyLabel(right_block), 1983 __ Branch(chunk_->GetAssemblyLabel(right_block),
1983 NegateCondition(cc), src1, src2); 1984 NegateCondition(cc), src1, src2);
1984 } else if (right_block == next_block) { 1985 } else if (right_block == next_block) {
1985 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); 1986 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2);
1986 } else { 1987 } else {
1987 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); 1988 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2);
1988 __ Branch(chunk_->GetAssemblyLabel(right_block)); 1989 __ Branch(chunk_->GetAssemblyLabel(right_block));
1989 } 1990 }
1990 } 1991 }
1991 1992
1992 1993
1993 void LCodeGen::EmitBranchF(int left_block, int right_block, 1994 template<class InstrType>
1995 void LCodeGen::EmitBranchF(InstrType instr,
1994 Condition cc, FPURegister src1, FPURegister src2) { 1996 Condition cc, FPURegister src1, FPURegister src2) {
1997 int right_block = instr->FalseDestination(chunk_);
1998 int left_block = instr->TrueDestination(chunk_);
1999
1995 int next_block = GetNextEmittedBlock(); 2000 int next_block = GetNextEmittedBlock();
1996 right_block = chunk_->LookupDestination(right_block);
1997 left_block = chunk_->LookupDestination(left_block);
1998 if (right_block == left_block) { 2001 if (right_block == left_block) {
1999 EmitGoto(left_block); 2002 EmitGoto(left_block);
2000 } else if (left_block == next_block) { 2003 } else if (left_block == next_block) {
2001 __ BranchF(chunk_->GetAssemblyLabel(right_block), NULL, 2004 __ BranchF(chunk_->GetAssemblyLabel(right_block), NULL,
2002 NegateCondition(cc), src1, src2); 2005 NegateCondition(cc), src1, src2);
2003 } else if (right_block == next_block) { 2006 } else if (right_block == next_block) {
2004 __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, cc, src1, src2); 2007 __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, cc, src1, src2);
2005 } else { 2008 } else {
2006 __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, cc, src1, src2); 2009 __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, cc, src1, src2);
2007 __ Branch(chunk_->GetAssemblyLabel(right_block)); 2010 __ Branch(chunk_->GetAssemblyLabel(right_block));
2008 } 2011 }
2009 } 2012 }
2010 2013
2011 2014
2012 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 2015 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
2013 __ stop("LDebugBreak"); 2016 __ stop("LDebugBreak");
2014 } 2017 }
2015 2018
2016 2019
2017 void LCodeGen::DoBranch(LBranch* instr) { 2020 void LCodeGen::DoBranch(LBranch* instr) {
2018 int true_block = chunk_->LookupDestination(instr->true_block_id());
2019 int false_block = chunk_->LookupDestination(instr->false_block_id());
2020
2021 Representation r = instr->hydrogen()->value()->representation(); 2021 Representation r = instr->hydrogen()->value()->representation();
2022 if (r.IsInteger32() || r.IsSmi()) { 2022 if (r.IsInteger32() || r.IsSmi()) {
2023 ASSERT(!info()->IsStub()); 2023 ASSERT(!info()->IsStub());
2024 Register reg = ToRegister(instr->value()); 2024 Register reg = ToRegister(instr->value());
2025 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); 2025 EmitBranch(instr, ne, reg, Operand(zero_reg));
2026 } else if (r.IsDouble()) { 2026 } else if (r.IsDouble()) {
2027 ASSERT(!info()->IsStub()); 2027 ASSERT(!info()->IsStub());
2028 DoubleRegister reg = ToDoubleRegister(instr->value()); 2028 DoubleRegister reg = ToDoubleRegister(instr->value());
2029 // Test the double value. Zero and NaN are false. 2029 // Test the double value. Zero and NaN are false.
2030 EmitBranchF(true_block, false_block, nue, reg, kDoubleRegZero); 2030 EmitBranchF(instr, nue, reg, kDoubleRegZero);
2031 } else { 2031 } else {
2032 ASSERT(r.IsTagged()); 2032 ASSERT(r.IsTagged());
2033 Register reg = ToRegister(instr->value()); 2033 Register reg = ToRegister(instr->value());
2034 HType type = instr->hydrogen()->value()->type(); 2034 HType type = instr->hydrogen()->value()->type();
2035 if (type.IsBoolean()) { 2035 if (type.IsBoolean()) {
2036 ASSERT(!info()->IsStub()); 2036 ASSERT(!info()->IsStub());
2037 __ LoadRoot(at, Heap::kTrueValueRootIndex); 2037 __ LoadRoot(at, Heap::kTrueValueRootIndex);
2038 EmitBranch(true_block, false_block, eq, reg, Operand(at)); 2038 EmitBranch(instr, eq, reg, Operand(at));
2039 } else if (type.IsSmi()) { 2039 } else if (type.IsSmi()) {
2040 ASSERT(!info()->IsStub()); 2040 ASSERT(!info()->IsStub());
2041 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); 2041 EmitBranch(instr, ne, reg, Operand(zero_reg));
2042 } else { 2042 } else {
2043 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2044 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2045
2046 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 2043 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2047 // Avoid deopts in the case where we've never executed this path before. 2044 // Avoid deopts in the case where we've never executed this path before.
2048 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 2045 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
2049 2046
2050 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 2047 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
2051 // undefined -> false. 2048 // undefined -> false.
2052 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 2049 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2053 __ Branch(false_label, eq, reg, Operand(at)); 2050 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2054 } 2051 }
2055 if (expected.Contains(ToBooleanStub::BOOLEAN)) { 2052 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
2056 // Boolean -> its value. 2053 // Boolean -> its value.
2057 __ LoadRoot(at, Heap::kTrueValueRootIndex); 2054 __ LoadRoot(at, Heap::kTrueValueRootIndex);
2058 __ Branch(true_label, eq, reg, Operand(at)); 2055 __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at));
2059 __ LoadRoot(at, Heap::kFalseValueRootIndex); 2056 __ LoadRoot(at, Heap::kFalseValueRootIndex);
2060 __ Branch(false_label, eq, reg, Operand(at)); 2057 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2061 } 2058 }
2062 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 2059 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
2063 // 'null' -> false. 2060 // 'null' -> false.
2064 __ LoadRoot(at, Heap::kNullValueRootIndex); 2061 __ LoadRoot(at, Heap::kNullValueRootIndex);
2065 __ Branch(false_label, eq, reg, Operand(at)); 2062 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2066 } 2063 }
2067 2064
2068 if (expected.Contains(ToBooleanStub::SMI)) { 2065 if (expected.Contains(ToBooleanStub::SMI)) {
2069 // Smis: 0 -> false, all other -> true. 2066 // Smis: 0 -> false, all other -> true.
2070 __ Branch(false_label, eq, reg, Operand(zero_reg)); 2067 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
2071 __ JumpIfSmi(reg, true_label); 2068 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2072 } else if (expected.NeedsMap()) { 2069 } else if (expected.NeedsMap()) {
2073 // If we need a map later and have a Smi -> deopt. 2070 // If we need a map later and have a Smi -> deopt.
2074 __ And(at, reg, Operand(kSmiTagMask)); 2071 __ And(at, reg, Operand(kSmiTagMask));
2075 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 2072 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
2076 } 2073 }
2077 2074
2078 const Register map = scratch0(); 2075 const Register map = scratch0();
2079 if (expected.NeedsMap()) { 2076 if (expected.NeedsMap()) {
2080 __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 2077 __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset));
2081 if (expected.CanBeUndetectable()) { 2078 if (expected.CanBeUndetectable()) {
2082 // Undetectable -> false. 2079 // Undetectable -> false.
2083 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); 2080 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
2084 __ And(at, at, Operand(1 << Map::kIsUndetectable)); 2081 __ And(at, at, Operand(1 << Map::kIsUndetectable));
2085 __ Branch(false_label, ne, at, Operand(zero_reg)); 2082 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
2086 } 2083 }
2087 } 2084 }
2088 2085
2089 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 2086 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
2090 // spec object -> true. 2087 // spec object -> true.
2091 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); 2088 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
2092 __ Branch(true_label, ge, at, Operand(FIRST_SPEC_OBJECT_TYPE)); 2089 __ Branch(instr->TrueLabel(chunk_),
2090 ge, at, Operand(FIRST_SPEC_OBJECT_TYPE));
2093 } 2091 }
2094 2092
2095 if (expected.Contains(ToBooleanStub::STRING)) { 2093 if (expected.Contains(ToBooleanStub::STRING)) {
2096 // String value -> false iff empty. 2094 // String value -> false iff empty.
2097 Label not_string; 2095 Label not_string;
2098 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); 2096 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
2099 __ Branch(&not_string, ge , at, Operand(FIRST_NONSTRING_TYPE)); 2097 __ Branch(&not_string, ge , at, Operand(FIRST_NONSTRING_TYPE));
2100 __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); 2098 __ lw(at, FieldMemOperand(reg, String::kLengthOffset));
2101 __ Branch(true_label, ne, at, Operand(zero_reg)); 2099 __ Branch(instr->TrueLabel(chunk_), ne, at, Operand(zero_reg));
2102 __ Branch(false_label); 2100 __ Branch(instr->FalseLabel(chunk_));
2103 __ bind(&not_string); 2101 __ bind(&not_string);
2104 } 2102 }
2105 2103
2106 if (expected.Contains(ToBooleanStub::SYMBOL)) { 2104 if (expected.Contains(ToBooleanStub::SYMBOL)) {
2107 // Symbol value -> true. 2105 // Symbol value -> true.
2108 const Register scratch = scratch1(); 2106 const Register scratch = scratch1();
2109 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 2107 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
2110 __ Branch(true_label, eq, scratch, Operand(SYMBOL_TYPE)); 2108 __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE));
2111 } 2109 }
2112 2110
2113 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2111 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2114 // heap number -> false iff +0, -0, or NaN. 2112 // heap number -> false iff +0, -0, or NaN.
2115 DoubleRegister dbl_scratch = double_scratch0(); 2113 DoubleRegister dbl_scratch = double_scratch0();
2116 Label not_heap_number; 2114 Label not_heap_number;
2117 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 2115 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
2118 __ Branch(&not_heap_number, ne, map, Operand(at)); 2116 __ Branch(&not_heap_number, ne, map, Operand(at));
2119 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 2117 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
2120 __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero); 2118 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2119 ne, dbl_scratch, kDoubleRegZero);
2121 // Falls through if dbl_scratch == 0. 2120 // Falls through if dbl_scratch == 0.
2122 __ Branch(false_label); 2121 __ Branch(instr->FalseLabel(chunk_));
2123 __ bind(&not_heap_number); 2122 __ bind(&not_heap_number);
2124 } 2123 }
2125 2124
2126 // We've seen something for the first time -> deopt. 2125 // We've seen something for the first time -> deopt.
2127 DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg)); 2126 DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg));
2128 } 2127 }
2129 } 2128 }
2130 } 2129 }
2131 2130
2132 2131
2133 void LCodeGen::EmitGoto(int block) { 2132 void LCodeGen::EmitGoto(int block) {
2134 if (!IsNextEmittedBlock(block)) { 2133 if (!IsNextEmittedBlock(block)) {
2135 __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); 2134 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
2136 } 2135 }
2137 } 2136 }
2138 2137
2139 2138
2140 void LCodeGen::DoGoto(LGoto* instr) { 2139 void LCodeGen::DoGoto(LGoto* instr) {
2141 EmitGoto(instr->block_id()); 2140 EmitGoto(instr->block_id());
2142 } 2141 }
2143 2142
2144 2143
2145 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2144 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
(...skipping 20 matching lines...) Expand all
2166 default: 2165 default:
2167 UNREACHABLE(); 2166 UNREACHABLE();
2168 } 2167 }
2169 return cond; 2168 return cond;
2170 } 2169 }
2171 2170
2172 2171
2173 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 2172 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
2174 LOperand* left = instr->left(); 2173 LOperand* left = instr->left();
2175 LOperand* right = instr->right(); 2174 LOperand* right = instr->right();
2176 int false_block = chunk_->LookupDestination(instr->false_block_id());
2177 int true_block = chunk_->LookupDestination(instr->true_block_id());
2178
2179 Condition cond = TokenToCondition(instr->op(), false); 2175 Condition cond = TokenToCondition(instr->op(), false);
2180 2176
2181 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2177 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2182 // We can statically evaluate the comparison. 2178 // We can statically evaluate the comparison.
2183 double left_val = ToDouble(LConstantOperand::cast(left)); 2179 double left_val = ToDouble(LConstantOperand::cast(left));
2184 double right_val = ToDouble(LConstantOperand::cast(right)); 2180 double right_val = ToDouble(LConstantOperand::cast(right));
2185 int next_block = 2181 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2186 EvalComparison(instr->op(), left_val, right_val) ? true_block 2182 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2187 : false_block;
2188 EmitGoto(next_block); 2183 EmitGoto(next_block);
2189 } else { 2184 } else {
2190 if (instr->is_double()) { 2185 if (instr->is_double()) {
2191 // Compare left and right as doubles and load the 2186 // Compare left and right as doubles and load the
2192 // resulting flags into the normal status register. 2187 // resulting flags into the normal status register.
2193 FPURegister left_reg = ToDoubleRegister(left); 2188 FPURegister left_reg = ToDoubleRegister(left);
2194 FPURegister right_reg = ToDoubleRegister(right); 2189 FPURegister right_reg = ToDoubleRegister(right);
2195 2190
2196 // If a NaN is involved, i.e. the result is unordered, 2191 // If a NaN is involved, i.e. the result is unordered,
2197 // jump to false block label. 2192 // jump to false block label.
2198 __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq, 2193 __ BranchF(NULL, instr->FalseLabel(chunk_), eq,
2199 left_reg, right_reg); 2194 left_reg, right_reg);
2200 2195
2201 EmitBranchF(true_block, false_block, cond, left_reg, right_reg); 2196 EmitBranchF(instr, cond, left_reg, right_reg);
2202 } else { 2197 } else {
2203 Register cmp_left; 2198 Register cmp_left;
2204 Operand cmp_right = Operand(0); 2199 Operand cmp_right = Operand(0);
2205 2200
2206 if (right->IsConstantOperand()) { 2201 if (right->IsConstantOperand()) {
2207 int32_t value = ToInteger32(LConstantOperand::cast(right)); 2202 int32_t value = ToInteger32(LConstantOperand::cast(right));
2208 if (instr->hydrogen_value()->representation().IsSmi()) { 2203 if (instr->hydrogen_value()->representation().IsSmi()) {
2209 cmp_left = ToRegister(left); 2204 cmp_left = ToRegister(left);
2210 cmp_right = Operand(Smi::FromInt(value)); 2205 cmp_right = Operand(Smi::FromInt(value));
2211 } else { 2206 } else {
2212 cmp_left = ToRegister(left); 2207 cmp_left = ToRegister(left);
2213 cmp_right = Operand(value); 2208 cmp_right = Operand(value);
2214 } 2209 }
2215 } else if (left->IsConstantOperand()) { 2210 } else if (left->IsConstantOperand()) {
2216 int32_t value = ToInteger32(LConstantOperand::cast(left)); 2211 int32_t value = ToInteger32(LConstantOperand::cast(left));
2217 if (instr->hydrogen_value()->representation().IsSmi()) { 2212 if (instr->hydrogen_value()->representation().IsSmi()) {
2218 cmp_left = ToRegister(right); 2213 cmp_left = ToRegister(right);
2219 cmp_right = Operand(Smi::FromInt(value)); 2214 cmp_right = Operand(Smi::FromInt(value));
2220 } else { 2215 } else {
2221 cmp_left = ToRegister(right); 2216 cmp_left = ToRegister(right);
2222 cmp_right = Operand(value); 2217 cmp_right = Operand(value);
2223 } 2218 }
2224 // We transposed the operands. Reverse the condition. 2219 // We transposed the operands. Reverse the condition.
2225 cond = ReverseCondition(cond); 2220 cond = ReverseCondition(cond);
2226 } else { 2221 } else {
2227 cmp_left = ToRegister(left); 2222 cmp_left = ToRegister(left);
2228 cmp_right = Operand(ToRegister(right)); 2223 cmp_right = Operand(ToRegister(right));
2229 } 2224 }
2230 2225
2231 EmitBranch(true_block, false_block, cond, cmp_left, cmp_right); 2226 EmitBranch(instr, cond, cmp_left, cmp_right);
2232 } 2227 }
2233 } 2228 }
2234 } 2229 }
2235 2230
2236 2231
2237 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2232 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2238 Register left = ToRegister(instr->left()); 2233 Register left = ToRegister(instr->left());
2239 Register right = ToRegister(instr->right()); 2234 Register right = ToRegister(instr->right());
2240 int false_block = chunk_->LookupDestination(instr->false_block_id());
2241 int true_block = chunk_->LookupDestination(instr->true_block_id());
2242 2235
2243 EmitBranch(true_block, false_block, eq, left, Operand(right)); 2236 EmitBranch(instr, eq, left, Operand(right));
2244 } 2237 }
2245 2238
2246 2239
2247 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 2240 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
2248 Register left = ToRegister(instr->left()); 2241 Register left = ToRegister(instr->left());
2249 int true_block = chunk_->LookupDestination(instr->true_block_id());
2250 int false_block = chunk_->LookupDestination(instr->false_block_id());
2251 2242
2252 EmitBranch(true_block, false_block, eq, left, 2243 EmitBranch(instr, eq, left, Operand(instr->hydrogen()->right()));
2253 Operand(instr->hydrogen()->right()));
2254 } 2244 }
2255 2245
2256 2246
2257 Condition LCodeGen::EmitIsObject(Register input, 2247 Condition LCodeGen::EmitIsObject(Register input,
2258 Register temp1, 2248 Register temp1,
2259 Register temp2, 2249 Register temp2,
2260 Label* is_not_object, 2250 Label* is_not_object,
2261 Label* is_object) { 2251 Label* is_object) {
2262 __ JumpIfSmi(input, is_not_object); 2252 __ JumpIfSmi(input, is_not_object);
2263 2253
(...skipping 14 matching lines...) Expand all
2278 2268
2279 return le; 2269 return le;
2280 } 2270 }
2281 2271
2282 2272
2283 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 2273 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2284 Register reg = ToRegister(instr->value()); 2274 Register reg = ToRegister(instr->value());
2285 Register temp1 = ToRegister(instr->temp()); 2275 Register temp1 = ToRegister(instr->temp());
2286 Register temp2 = scratch0(); 2276 Register temp2 = scratch0();
2287 2277
2288 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2278 Condition true_cond =
2289 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2279 EmitIsObject(reg, temp1, temp2,
2290 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2280 instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2291 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2292 2281
2293 Condition true_cond = 2282 EmitBranch(instr, true_cond, temp2,
2294 EmitIsObject(reg, temp1, temp2, false_label, true_label);
2295
2296 EmitBranch(true_block, false_block, true_cond, temp2,
2297 Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2283 Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
2298 } 2284 }
2299 2285
2300 2286
2301 Condition LCodeGen::EmitIsString(Register input, 2287 Condition LCodeGen::EmitIsString(Register input,
2302 Register temp1, 2288 Register temp1,
2303 Label* is_not_string) { 2289 Label* is_not_string) {
2304 __ JumpIfSmi(input, is_not_string); 2290 __ JumpIfSmi(input, is_not_string);
2305 __ GetObjectType(input, temp1, temp1); 2291 __ GetObjectType(input, temp1, temp1);
2306 2292
2307 return lt; 2293 return lt;
2308 } 2294 }
2309 2295
2310 2296
2311 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2297 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2312 Register reg = ToRegister(instr->value()); 2298 Register reg = ToRegister(instr->value());
2313 Register temp1 = ToRegister(instr->temp()); 2299 Register temp1 = ToRegister(instr->temp());
2314 2300
2315 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2301 Condition true_cond =
2316 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2302 EmitIsString(reg, temp1, instr->FalseLabel(chunk_));
2317 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2318 2303
2319 Condition true_cond = 2304 EmitBranch(instr, true_cond, temp1,
2320 EmitIsString(reg, temp1, false_label);
2321
2322 EmitBranch(true_block, false_block, true_cond, temp1,
2323 Operand(FIRST_NONSTRING_TYPE)); 2305 Operand(FIRST_NONSTRING_TYPE));
2324 } 2306 }
2325 2307
2326 2308
2327 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2309 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2328 int true_block = chunk_->LookupDestination(instr->true_block_id());
2329 int false_block = chunk_->LookupDestination(instr->false_block_id());
2330
2331 Register input_reg = EmitLoadRegister(instr->value(), at); 2310 Register input_reg = EmitLoadRegister(instr->value(), at);
2332 __ And(at, input_reg, kSmiTagMask); 2311 __ And(at, input_reg, kSmiTagMask);
2333 EmitBranch(true_block, false_block, eq, at, Operand(zero_reg)); 2312 EmitBranch(instr, eq, at, Operand(zero_reg));
2334 } 2313 }
2335 2314
2336 2315
2337 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2316 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2338 Register input = ToRegister(instr->value()); 2317 Register input = ToRegister(instr->value());
2339 Register temp = ToRegister(instr->temp()); 2318 Register temp = ToRegister(instr->temp());
2340 2319
2341 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2320 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2342 int false_block = chunk_->LookupDestination(instr->false_block_id());
2343
2344 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
2345 __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset)); 2321 __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset));
2346 __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); 2322 __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
2347 __ And(at, temp, Operand(1 << Map::kIsUndetectable)); 2323 __ And(at, temp, Operand(1 << Map::kIsUndetectable));
2348 EmitBranch(true_block, false_block, ne, at, Operand(zero_reg)); 2324 EmitBranch(instr, ne, at, Operand(zero_reg));
2349 } 2325 }
2350 2326
2351 2327
2352 static Condition ComputeCompareCondition(Token::Value op) { 2328 static Condition ComputeCompareCondition(Token::Value op) {
2353 switch (op) { 2329 switch (op) {
2354 case Token::EQ_STRICT: 2330 case Token::EQ_STRICT:
2355 case Token::EQ: 2331 case Token::EQ:
2356 return eq; 2332 return eq;
2357 case Token::LT: 2333 case Token::LT:
2358 return lt; 2334 return lt;
2359 case Token::GT: 2335 case Token::GT:
2360 return gt; 2336 return gt;
2361 case Token::LTE: 2337 case Token::LTE:
2362 return le; 2338 return le;
2363 case Token::GTE: 2339 case Token::GTE:
2364 return ge; 2340 return ge;
2365 default: 2341 default:
2366 UNREACHABLE(); 2342 UNREACHABLE();
2367 return kNoCondition; 2343 return kNoCondition;
2368 } 2344 }
2369 } 2345 }
2370 2346
2371 2347
2372 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 2348 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2373 Token::Value op = instr->op(); 2349 Token::Value op = instr->op();
2374 int true_block = chunk_->LookupDestination(instr->true_block_id());
2375 int false_block = chunk_->LookupDestination(instr->false_block_id());
2376 2350
2377 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2351 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2378 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2352 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2379 2353
2380 Condition condition = ComputeCompareCondition(op); 2354 Condition condition = ComputeCompareCondition(op);
2381 2355
2382 EmitBranch(true_block, false_block, condition, v0, Operand(zero_reg)); 2356 EmitBranch(instr, condition, v0, Operand(zero_reg));
2383 } 2357 }
2384 2358
2385 2359
2386 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 2360 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2387 InstanceType from = instr->from(); 2361 InstanceType from = instr->from();
2388 InstanceType to = instr->to(); 2362 InstanceType to = instr->to();
2389 if (from == FIRST_TYPE) return to; 2363 if (from == FIRST_TYPE) return to;
2390 ASSERT(from == to || to == LAST_TYPE); 2364 ASSERT(from == to || to == LAST_TYPE);
2391 return from; 2365 return from;
2392 } 2366 }
2393 2367
2394 2368
2395 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 2369 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2396 InstanceType from = instr->from(); 2370 InstanceType from = instr->from();
2397 InstanceType to = instr->to(); 2371 InstanceType to = instr->to();
2398 if (from == to) return eq; 2372 if (from == to) return eq;
2399 if (to == LAST_TYPE) return hs; 2373 if (to == LAST_TYPE) return hs;
2400 if (from == FIRST_TYPE) return ls; 2374 if (from == FIRST_TYPE) return ls;
2401 UNREACHABLE(); 2375 UNREACHABLE();
2402 return eq; 2376 return eq;
2403 } 2377 }
2404 2378
2405 2379
2406 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2380 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2407 Register scratch = scratch0(); 2381 Register scratch = scratch0();
2408 Register input = ToRegister(instr->value()); 2382 Register input = ToRegister(instr->value());
2409 2383
2410 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2384 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2411 int false_block = chunk_->LookupDestination(instr->false_block_id());
2412
2413 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2414
2415 __ JumpIfSmi(input, false_label);
2416 2385
2417 __ GetObjectType(input, scratch, scratch); 2386 __ GetObjectType(input, scratch, scratch);
2418 EmitBranch(true_block, 2387 EmitBranch(instr,
2419 false_block,
2420 BranchCondition(instr->hydrogen()), 2388 BranchCondition(instr->hydrogen()),
2421 scratch, 2389 scratch,
2422 Operand(TestType(instr->hydrogen()))); 2390 Operand(TestType(instr->hydrogen())));
2423 } 2391 }
2424 2392
2425 2393
2426 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2394 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2427 Register input = ToRegister(instr->value()); 2395 Register input = ToRegister(instr->value());
2428 Register result = ToRegister(instr->result()); 2396 Register result = ToRegister(instr->result());
2429 2397
2430 __ AssertString(input); 2398 __ AssertString(input);
2431 2399
2432 __ lw(result, FieldMemOperand(input, String::kHashFieldOffset)); 2400 __ lw(result, FieldMemOperand(input, String::kHashFieldOffset));
2433 __ IndexFromHash(result, result); 2401 __ IndexFromHash(result, result);
2434 } 2402 }
2435 2403
2436 2404
2437 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2405 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2438 LHasCachedArrayIndexAndBranch* instr) { 2406 LHasCachedArrayIndexAndBranch* instr) {
2439 Register input = ToRegister(instr->value()); 2407 Register input = ToRegister(instr->value());
2440 Register scratch = scratch0(); 2408 Register scratch = scratch0();
2441 2409
2442 int true_block = chunk_->LookupDestination(instr->true_block_id());
2443 int false_block = chunk_->LookupDestination(instr->false_block_id());
2444
2445 __ lw(scratch, 2410 __ lw(scratch,
2446 FieldMemOperand(input, String::kHashFieldOffset)); 2411 FieldMemOperand(input, String::kHashFieldOffset));
2447 __ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask)); 2412 __ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask));
2448 EmitBranch(true_block, false_block, eq, at, Operand(zero_reg)); 2413 EmitBranch(instr, eq, at, Operand(zero_reg));
2449 } 2414 }
2450 2415
2451 2416
2452 // Branches to a label or falls through with the answer in flags. Trashes 2417 // Branches to a label or falls through with the answer in flags. Trashes
2453 // the temp registers, but not the input. 2418 // the temp registers, but not the input.
2454 void LCodeGen::EmitClassOfTest(Label* is_true, 2419 void LCodeGen::EmitClassOfTest(Label* is_true,
2455 Label* is_false, 2420 Label* is_false,
2456 Handle<String>class_name, 2421 Handle<String>class_name,
2457 Register input, 2422 Register input,
2458 Register temp, 2423 Register temp,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2514 // On MIPS, the caller must do the comparison with Handle<String>class_name. 2479 // On MIPS, the caller must do the comparison with Handle<String>class_name.
2515 } 2480 }
2516 2481
2517 2482
2518 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2483 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2519 Register input = ToRegister(instr->value()); 2484 Register input = ToRegister(instr->value());
2520 Register temp = scratch0(); 2485 Register temp = scratch0();
2521 Register temp2 = ToRegister(instr->temp()); 2486 Register temp2 = ToRegister(instr->temp());
2522 Handle<String> class_name = instr->hydrogen()->class_name(); 2487 Handle<String> class_name = instr->hydrogen()->class_name();
2523 2488
2524 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2489 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2525 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2490 class_name, input, temp, temp2);
2526 2491
2527 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2492 EmitBranch(instr, eq, temp, Operand(class_name));
2528 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2529
2530 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2531
2532 EmitBranch(true_block, false_block, eq, temp, Operand(class_name));
2533 } 2493 }
2534 2494
2535 2495
2536 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2496 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2537 Register reg = ToRegister(instr->value()); 2497 Register reg = ToRegister(instr->value());
2538 Register temp = ToRegister(instr->temp()); 2498 Register temp = ToRegister(instr->temp());
2539 int true_block = instr->true_block_id();
2540 int false_block = instr->false_block_id();
2541 2499
2542 __ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 2500 __ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
2543 EmitBranch(true_block, false_block, eq, temp, Operand(instr->map())); 2501 EmitBranch(instr, eq, temp, Operand(instr->map()));
2544 } 2502 }
2545 2503
2546 2504
2547 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2505 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2548 Label true_label, done; 2506 Label true_label, done;
2549 ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0. 2507 ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0.
2550 ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1. 2508 ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1.
2551 Register result = ToRegister(instr->result()); 2509 Register result = ToRegister(instr->result());
2552 ASSERT(result.is(v0)); 2510 ASSERT(result.is(v0));
2553 2511
(...skipping 2973 matching lines...) Expand 10 before | Expand all | Expand 10 after
5527 void LCodeGen::DoTypeof(LTypeof* instr) { 5485 void LCodeGen::DoTypeof(LTypeof* instr) {
5528 ASSERT(ToRegister(instr->result()).is(v0)); 5486 ASSERT(ToRegister(instr->result()).is(v0));
5529 Register input = ToRegister(instr->value()); 5487 Register input = ToRegister(instr->value());
5530 __ push(input); 5488 __ push(input);
5531 CallRuntime(Runtime::kTypeof, 1, instr); 5489 CallRuntime(Runtime::kTypeof, 1, instr);
5532 } 5490 }
5533 5491
5534 5492
5535 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5493 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5536 Register input = ToRegister(instr->value()); 5494 Register input = ToRegister(instr->value());
5537 int true_block = chunk_->LookupDestination(instr->true_block_id());
5538 int false_block = chunk_->LookupDestination(instr->false_block_id());
5539 Label* true_label = chunk_->GetAssemblyLabel(true_block);
5540 Label* false_label = chunk_->GetAssemblyLabel(false_block);
5541 5495
5542 Register cmp1 = no_reg; 5496 Register cmp1 = no_reg;
5543 Operand cmp2 = Operand(no_reg); 5497 Operand cmp2 = Operand(no_reg);
5544 5498
5545 Condition final_branch_condition = EmitTypeofIs(true_label, 5499 Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_),
5546 false_label, 5500 instr->FalseLabel(chunk_),
5547 input, 5501 input,
5548 instr->type_literal(), 5502 instr->type_literal(),
5549 cmp1, 5503 cmp1,
5550 cmp2); 5504 cmp2);
5551 5505
5552 ASSERT(cmp1.is_valid()); 5506 ASSERT(cmp1.is_valid());
5553 ASSERT(!cmp2.is_reg() || cmp2.rm().is_valid()); 5507 ASSERT(!cmp2.is_reg() || cmp2.rm().is_valid());
5554 5508
5555 if (final_branch_condition != kNoCondition) { 5509 if (final_branch_condition != kNoCondition) {
5556 EmitBranch(true_block, false_block, final_branch_condition, cmp1, cmp2); 5510 EmitBranch(instr, final_branch_condition, cmp1, cmp2);
5557 } 5511 }
5558 } 5512 }
5559 5513
5560 5514
5561 Condition LCodeGen::EmitTypeofIs(Label* true_label, 5515 Condition LCodeGen::EmitTypeofIs(Label* true_label,
5562 Label* false_label, 5516 Label* false_label,
5563 Register input, 5517 Register input,
5564 Handle<String> type_name, 5518 Handle<String> type_name,
5565 Register& cmp1, 5519 Register& cmp1,
5566 Operand& cmp2) { 5520 Operand& cmp2) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
5659 cmp2 = Operand(zero_reg); // Set to valid regs, to avoid caller assertion. 5613 cmp2 = Operand(zero_reg); // Set to valid regs, to avoid caller assertion.
5660 __ Branch(false_label); 5614 __ Branch(false_label);
5661 } 5615 }
5662 5616
5663 return final_branch_condition; 5617 return final_branch_condition;
5664 } 5618 }
5665 5619
5666 5620
5667 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5621 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5668 Register temp1 = ToRegister(instr->temp()); 5622 Register temp1 = ToRegister(instr->temp());
5669 int true_block = chunk_->LookupDestination(instr->true_block_id());
5670 int false_block = chunk_->LookupDestination(instr->false_block_id());
5671 5623
5672 EmitIsConstructCall(temp1, scratch0()); 5624 EmitIsConstructCall(temp1, scratch0());
5673 5625
5674 EmitBranch(true_block, false_block, eq, temp1, 5626 EmitBranch(instr, eq, temp1,
5675 Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 5627 Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
5676 } 5628 }
5677 5629
5678 5630
5679 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { 5631 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
5680 ASSERT(!temp1.is(temp2)); 5632 ASSERT(!temp1.is(temp2));
5681 // Get the frame pointer for the calling frame. 5633 // Get the frame pointer for the calling frame.
5682 __ lw(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 5634 __ lw(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
5683 5635
5684 // Skip the arguments adaptor frame if it exists. 5636 // Skip the arguments adaptor frame if it exists.
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
5922 __ Subu(scratch, result, scratch); 5874 __ Subu(scratch, result, scratch);
5923 __ lw(result, FieldMemOperand(scratch, 5875 __ lw(result, FieldMemOperand(scratch,
5924 FixedArray::kHeaderSize - kPointerSize)); 5876 FixedArray::kHeaderSize - kPointerSize));
5925 __ bind(&done); 5877 __ bind(&done);
5926 } 5878 }
5927 5879
5928 5880
5929 #undef __ 5881 #undef __
5930 5882
5931 } } // namespace v8::internal 5883 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698