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

Side by Side Diff: src/ia32/lithium-codegen-ia32.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/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.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 2069 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 2080
2081 2081
2082 int LCodeGen::GetNextEmittedBlock() const { 2082 int LCodeGen::GetNextEmittedBlock() const {
2083 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 2083 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
2084 if (!chunk_->GetLabel(i)->HasReplacement()) return i; 2084 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
2085 } 2085 }
2086 return -1; 2086 return -1;
2087 } 2087 }
2088 2088
2089 2089
2090 void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { 2090 template<class InstrType>
2091 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
2092 int right_block = instr->FalseDestination(chunk_);
2093 int left_block = instr->TrueDestination(chunk_);
2094
2091 int next_block = GetNextEmittedBlock(); 2095 int next_block = GetNextEmittedBlock();
2092 right_block = chunk_->LookupDestination(right_block);
2093 left_block = chunk_->LookupDestination(left_block);
2094 2096
2095 if (right_block == left_block) { 2097 if (right_block == left_block) {
2096 EmitGoto(left_block); 2098 EmitGoto(left_block);
2097 } else if (left_block == next_block) { 2099 } else if (left_block == next_block) {
2098 __ j(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block)); 2100 __ j(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block));
2099 } else if (right_block == next_block) { 2101 } else if (right_block == next_block) {
2100 __ j(cc, chunk_->GetAssemblyLabel(left_block)); 2102 __ j(cc, chunk_->GetAssemblyLabel(left_block));
2101 } else { 2103 } else {
2102 __ j(cc, chunk_->GetAssemblyLabel(left_block)); 2104 __ j(cc, chunk_->GetAssemblyLabel(left_block));
2103 __ jmp(chunk_->GetAssemblyLabel(right_block)); 2105 __ jmp(chunk_->GetAssemblyLabel(right_block));
2104 } 2106 }
2105 } 2107 }
2106 2108
2107 2109
2108 void LCodeGen::DoBranch(LBranch* instr) { 2110 void LCodeGen::DoBranch(LBranch* instr) {
2109 int true_block = chunk_->LookupDestination(instr->true_block_id());
2110 int false_block = chunk_->LookupDestination(instr->false_block_id());
2111
2112 Representation r = instr->hydrogen()->value()->representation(); 2111 Representation r = instr->hydrogen()->value()->representation();
2113 if (r.IsSmiOrInteger32()) { 2112 if (r.IsSmiOrInteger32()) {
2114 ASSERT(!info()->IsStub()); 2113 ASSERT(!info()->IsStub());
2115 Register reg = ToRegister(instr->value()); 2114 Register reg = ToRegister(instr->value());
2116 __ test(reg, Operand(reg)); 2115 __ test(reg, Operand(reg));
2117 EmitBranch(true_block, false_block, not_zero); 2116 EmitBranch(instr, not_zero);
2118 } else if (r.IsDouble()) { 2117 } else if (r.IsDouble()) {
2119 ASSERT(!info()->IsStub()); 2118 ASSERT(!info()->IsStub());
2120 CpuFeatureScope scope(masm(), SSE2); 2119 CpuFeatureScope scope(masm(), SSE2);
2121 XMMRegister reg = ToDoubleRegister(instr->value()); 2120 XMMRegister reg = ToDoubleRegister(instr->value());
2122 __ xorps(xmm0, xmm0); 2121 __ xorps(xmm0, xmm0);
2123 __ ucomisd(reg, xmm0); 2122 __ ucomisd(reg, xmm0);
2124 EmitBranch(true_block, false_block, not_equal); 2123 EmitBranch(instr, not_equal);
2125 } else { 2124 } else {
2126 ASSERT(r.IsTagged()); 2125 ASSERT(r.IsTagged());
2127 Register reg = ToRegister(instr->value()); 2126 Register reg = ToRegister(instr->value());
2128 HType type = instr->hydrogen()->value()->type(); 2127 HType type = instr->hydrogen()->value()->type();
2129 if (type.IsBoolean()) { 2128 if (type.IsBoolean()) {
2130 ASSERT(!info()->IsStub()); 2129 ASSERT(!info()->IsStub());
2131 __ cmp(reg, factory()->true_value()); 2130 __ cmp(reg, factory()->true_value());
2132 EmitBranch(true_block, false_block, equal); 2131 EmitBranch(instr, equal);
2133 } else if (type.IsSmi()) { 2132 } else if (type.IsSmi()) {
2134 ASSERT(!info()->IsStub()); 2133 ASSERT(!info()->IsStub());
2135 __ test(reg, Operand(reg)); 2134 __ test(reg, Operand(reg));
2136 EmitBranch(true_block, false_block, not_equal); 2135 EmitBranch(instr, not_equal);
2137 } else { 2136 } else {
2138 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2139 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2140
2141 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 2137 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2142 // Avoid deopts in the case where we've never executed this path before. 2138 // Avoid deopts in the case where we've never executed this path before.
2143 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 2139 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
2144 2140
2145 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 2141 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
2146 // undefined -> false. 2142 // undefined -> false.
2147 __ cmp(reg, factory()->undefined_value()); 2143 __ cmp(reg, factory()->undefined_value());
2148 __ j(equal, false_label); 2144 __ j(equal, instr->FalseLabel(chunk_));
2149 } 2145 }
2150 if (expected.Contains(ToBooleanStub::BOOLEAN)) { 2146 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
2151 // true -> true. 2147 // true -> true.
2152 __ cmp(reg, factory()->true_value()); 2148 __ cmp(reg, factory()->true_value());
2153 __ j(equal, true_label); 2149 __ j(equal, instr->TrueLabel(chunk_));
2154 // false -> false. 2150 // false -> false.
2155 __ cmp(reg, factory()->false_value()); 2151 __ cmp(reg, factory()->false_value());
2156 __ j(equal, false_label); 2152 __ j(equal, instr->FalseLabel(chunk_));
2157 } 2153 }
2158 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 2154 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
2159 // 'null' -> false. 2155 // 'null' -> false.
2160 __ cmp(reg, factory()->null_value()); 2156 __ cmp(reg, factory()->null_value());
2161 __ j(equal, false_label); 2157 __ j(equal, instr->FalseLabel(chunk_));
2162 } 2158 }
2163 2159
2164 if (expected.Contains(ToBooleanStub::SMI)) { 2160 if (expected.Contains(ToBooleanStub::SMI)) {
2165 // Smis: 0 -> false, all other -> true. 2161 // Smis: 0 -> false, all other -> true.
2166 __ test(reg, Operand(reg)); 2162 __ test(reg, Operand(reg));
2167 __ j(equal, false_label); 2163 __ j(equal, instr->FalseLabel(chunk_));
2168 __ JumpIfSmi(reg, true_label); 2164 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2169 } else if (expected.NeedsMap()) { 2165 } else if (expected.NeedsMap()) {
2170 // If we need a map later and have a Smi -> deopt. 2166 // If we need a map later and have a Smi -> deopt.
2171 __ test(reg, Immediate(kSmiTagMask)); 2167 __ test(reg, Immediate(kSmiTagMask));
2172 DeoptimizeIf(zero, instr->environment()); 2168 DeoptimizeIf(zero, instr->environment());
2173 } 2169 }
2174 2170
2175 Register map = no_reg; // Keep the compiler happy. 2171 Register map = no_reg; // Keep the compiler happy.
2176 if (expected.NeedsMap()) { 2172 if (expected.NeedsMap()) {
2177 map = ToRegister(instr->temp()); 2173 map = ToRegister(instr->temp());
2178 ASSERT(!map.is(reg)); 2174 ASSERT(!map.is(reg));
2179 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); 2175 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset));
2180 2176
2181 if (expected.CanBeUndetectable()) { 2177 if (expected.CanBeUndetectable()) {
2182 // Undetectable -> false. 2178 // Undetectable -> false.
2183 __ test_b(FieldOperand(map, Map::kBitFieldOffset), 2179 __ test_b(FieldOperand(map, Map::kBitFieldOffset),
2184 1 << Map::kIsUndetectable); 2180 1 << Map::kIsUndetectable);
2185 __ j(not_zero, false_label); 2181 __ j(not_zero, instr->FalseLabel(chunk_));
2186 } 2182 }
2187 } 2183 }
2188 2184
2189 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 2185 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
2190 // spec object -> true. 2186 // spec object -> true.
2191 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 2187 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
2192 __ j(above_equal, true_label); 2188 __ j(above_equal, instr->TrueLabel(chunk_));
2193 } 2189 }
2194 2190
2195 if (expected.Contains(ToBooleanStub::STRING)) { 2191 if (expected.Contains(ToBooleanStub::STRING)) {
2196 // String value -> false iff empty. 2192 // String value -> false iff empty.
2197 Label not_string; 2193 Label not_string;
2198 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 2194 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
2199 __ j(above_equal, &not_string, Label::kNear); 2195 __ j(above_equal, &not_string, Label::kNear);
2200 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 2196 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0));
2201 __ j(not_zero, true_label); 2197 __ j(not_zero, instr->TrueLabel(chunk_));
2202 __ jmp(false_label); 2198 __ jmp(instr->FalseLabel(chunk_));
2203 __ bind(&not_string); 2199 __ bind(&not_string);
2204 } 2200 }
2205 2201
2206 if (expected.Contains(ToBooleanStub::SYMBOL)) { 2202 if (expected.Contains(ToBooleanStub::SYMBOL)) {
2207 // Symbol value -> true. 2203 // Symbol value -> true.
2208 __ CmpInstanceType(map, SYMBOL_TYPE); 2204 __ CmpInstanceType(map, SYMBOL_TYPE);
2209 __ j(equal, true_label); 2205 __ j(equal, instr->TrueLabel(chunk_));
2210 } 2206 }
2211 2207
2212 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2208 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2213 // heap number -> false iff +0, -0, or NaN. 2209 // heap number -> false iff +0, -0, or NaN.
2214 Label not_heap_number; 2210 Label not_heap_number;
2215 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2211 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2216 factory()->heap_number_map()); 2212 factory()->heap_number_map());
2217 __ j(not_equal, &not_heap_number, Label::kNear); 2213 __ j(not_equal, &not_heap_number, Label::kNear);
2218 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2214 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
2219 CpuFeatureScope scope(masm(), SSE2); 2215 CpuFeatureScope scope(masm(), SSE2);
2220 __ xorps(xmm0, xmm0); 2216 __ xorps(xmm0, xmm0);
2221 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 2217 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset));
2222 } else { 2218 } else {
2223 __ fldz(); 2219 __ fldz();
2224 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 2220 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
2225 __ FCmp(); 2221 __ FCmp();
2226 } 2222 }
2227 __ j(zero, false_label); 2223 __ j(zero, instr->FalseLabel(chunk_));
2228 __ jmp(true_label); 2224 __ jmp(instr->TrueLabel(chunk_));
2229 __ bind(&not_heap_number); 2225 __ bind(&not_heap_number);
2230 } 2226 }
2231 2227
2232 // We've seen something for the first time -> deopt. 2228 // We've seen something for the first time -> deopt.
2233 DeoptimizeIf(no_condition, instr->environment()); 2229 DeoptimizeIf(no_condition, instr->environment());
2234 } 2230 }
2235 } 2231 }
2236 } 2232 }
2237 2233
2238 2234
2239 void LCodeGen::EmitGoto(int block) { 2235 void LCodeGen::EmitGoto(int block) {
2240 if (!IsNextEmittedBlock(block)) { 2236 if (!IsNextEmittedBlock(block)) {
2241 __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); 2237 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
2242 } 2238 }
2243 } 2239 }
2244 2240
2245 2241
2246 void LCodeGen::DoGoto(LGoto* instr) { 2242 void LCodeGen::DoGoto(LGoto* instr) {
2247 EmitGoto(instr->block_id()); 2243 EmitGoto(instr->block_id());
2248 } 2244 }
2249 2245
2250 2246
2251 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2247 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
(...skipping 20 matching lines...) Expand all
2272 default: 2268 default:
2273 UNREACHABLE(); 2269 UNREACHABLE();
2274 } 2270 }
2275 return cond; 2271 return cond;
2276 } 2272 }
2277 2273
2278 2274
2279 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 2275 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
2280 LOperand* left = instr->left(); 2276 LOperand* left = instr->left();
2281 LOperand* right = instr->right(); 2277 LOperand* right = instr->right();
2282 int false_block = chunk_->LookupDestination(instr->false_block_id());
2283 int true_block = chunk_->LookupDestination(instr->true_block_id());
2284 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 2278 Condition cc = TokenToCondition(instr->op(), instr->is_double());
2285 2279
2286 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2280 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2287 // We can statically evaluate the comparison. 2281 // We can statically evaluate the comparison.
2288 double left_val = ToDouble(LConstantOperand::cast(left)); 2282 double left_val = ToDouble(LConstantOperand::cast(left));
2289 double right_val = ToDouble(LConstantOperand::cast(right)); 2283 double right_val = ToDouble(LConstantOperand::cast(right));
2290 int next_block = 2284 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2291 EvalComparison(instr->op(), left_val, right_val) ? true_block 2285 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2292 : false_block;
2293 EmitGoto(next_block); 2286 EmitGoto(next_block);
2294 } else { 2287 } else {
2295 if (instr->is_double()) { 2288 if (instr->is_double()) {
2296 CpuFeatureScope scope(masm(), SSE2); 2289 CpuFeatureScope scope(masm(), SSE2);
2297 // Don't base result on EFLAGS when a NaN is involved. Instead 2290 // Don't base result on EFLAGS when a NaN is involved. Instead
2298 // jump to the false block. 2291 // jump to the false block.
2299 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 2292 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
2300 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); 2293 __ j(parity_even, instr->FalseLabel(chunk_));
2301 } else { 2294 } else {
2302 if (right->IsConstantOperand()) { 2295 if (right->IsConstantOperand()) {
2303 int32_t const_value = ToInteger32(LConstantOperand::cast(right)); 2296 int32_t const_value = ToInteger32(LConstantOperand::cast(right));
2304 if (instr->hydrogen_value()->representation().IsSmi()) { 2297 if (instr->hydrogen_value()->representation().IsSmi()) {
2305 __ cmp(ToOperand(left), Immediate(Smi::FromInt(const_value))); 2298 __ cmp(ToOperand(left), Immediate(Smi::FromInt(const_value)));
2306 } else { 2299 } else {
2307 __ cmp(ToOperand(left), Immediate(const_value)); 2300 __ cmp(ToOperand(left), Immediate(const_value));
2308 } 2301 }
2309 } else if (left->IsConstantOperand()) { 2302 } else if (left->IsConstantOperand()) {
2310 int32_t const_value = ToInteger32(LConstantOperand::cast(left)); 2303 int32_t const_value = ToInteger32(LConstantOperand::cast(left));
2311 if (instr->hydrogen_value()->representation().IsSmi()) { 2304 if (instr->hydrogen_value()->representation().IsSmi()) {
2312 __ cmp(ToOperand(right), Immediate(Smi::FromInt(const_value))); 2305 __ cmp(ToOperand(right), Immediate(Smi::FromInt(const_value)));
2313 } else { 2306 } else {
2314 __ cmp(ToOperand(right), Immediate(const_value)); 2307 __ cmp(ToOperand(right), Immediate(const_value));
2315 } 2308 }
2316 // We transposed the operands. Reverse the condition. 2309 // We transposed the operands. Reverse the condition.
2317 cc = ReverseCondition(cc); 2310 cc = ReverseCondition(cc);
2318 } else { 2311 } else {
2319 __ cmp(ToRegister(left), ToOperand(right)); 2312 __ cmp(ToRegister(left), ToOperand(right));
2320 } 2313 }
2321 } 2314 }
2322 EmitBranch(true_block, false_block, cc); 2315 EmitBranch(instr, cc);
2323 } 2316 }
2324 } 2317 }
2325 2318
2326 2319
2327 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2320 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2328 Register left = ToRegister(instr->left()); 2321 Register left = ToRegister(instr->left());
2329 int false_block = chunk_->LookupDestination(instr->false_block_id());
2330 int true_block = chunk_->LookupDestination(instr->true_block_id());
2331 2322
2332 if (instr->right()->IsConstantOperand()) { 2323 if (instr->right()->IsConstantOperand()) {
2333 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); 2324 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2334 __ CmpObject(left, right); 2325 __ CmpObject(left, right);
2335 } else { 2326 } else {
2336 Operand right = ToOperand(instr->right()); 2327 Operand right = ToOperand(instr->right());
2337 __ cmp(left, right); 2328 __ cmp(left, right);
2338 } 2329 }
2339 EmitBranch(true_block, false_block, equal); 2330 EmitBranch(instr, equal);
2340 } 2331 }
2341 2332
2342 2333
2343 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 2334 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
2344 Register left = ToRegister(instr->left()); 2335 Register left = ToRegister(instr->left());
2345 int true_block = chunk_->LookupDestination(instr->true_block_id());
2346 int false_block = chunk_->LookupDestination(instr->false_block_id());
2347 2336
2348 __ cmp(left, instr->hydrogen()->right()); 2337 __ cmp(left, instr->hydrogen()->right());
2349 EmitBranch(true_block, false_block, equal); 2338 EmitBranch(instr, equal);
2350 } 2339 }
2351 2340
2352 2341
2353 Condition LCodeGen::EmitIsObject(Register input, 2342 Condition LCodeGen::EmitIsObject(Register input,
2354 Register temp1, 2343 Register temp1,
2355 Label* is_not_object, 2344 Label* is_not_object,
2356 Label* is_object) { 2345 Label* is_object) {
2357 __ JumpIfSmi(input, is_not_object); 2346 __ JumpIfSmi(input, is_not_object);
2358 2347
2359 __ cmp(input, isolate()->factory()->null_value()); 2348 __ cmp(input, isolate()->factory()->null_value());
(...skipping 10 matching lines...) Expand all
2370 __ j(below, is_not_object); 2359 __ j(below, is_not_object);
2371 __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 2360 __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
2372 return below_equal; 2361 return below_equal;
2373 } 2362 }
2374 2363
2375 2364
2376 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 2365 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2377 Register reg = ToRegister(instr->value()); 2366 Register reg = ToRegister(instr->value());
2378 Register temp = ToRegister(instr->temp()); 2367 Register temp = ToRegister(instr->temp());
2379 2368
2380 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2369 Condition true_cond = EmitIsObject(
2381 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2370 reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2382 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2383 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2384 2371
2385 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label); 2372 EmitBranch(instr, true_cond);
2386
2387 EmitBranch(true_block, false_block, true_cond);
2388 } 2373 }
2389 2374
2390 2375
2391 Condition LCodeGen::EmitIsString(Register input, 2376 Condition LCodeGen::EmitIsString(Register input,
2392 Register temp1, 2377 Register temp1,
2393 Label* is_not_string) { 2378 Label* is_not_string) {
2394 __ JumpIfSmi(input, is_not_string); 2379 __ JumpIfSmi(input, is_not_string);
2395 2380
2396 Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 2381 Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
2397 2382
2398 return cond; 2383 return cond;
2399 } 2384 }
2400 2385
2401 2386
2402 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2387 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2403 Register reg = ToRegister(instr->value()); 2388 Register reg = ToRegister(instr->value());
2404 Register temp = ToRegister(instr->temp()); 2389 Register temp = ToRegister(instr->temp());
2405 2390
2406 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2391 Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_));
2407 int false_block = chunk_->LookupDestination(instr->false_block_id());
2408 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2409 2392
2410 Condition true_cond = EmitIsString(reg, temp, false_label); 2393 EmitBranch(instr, true_cond);
2411
2412 EmitBranch(true_block, false_block, true_cond);
2413 } 2394 }
2414 2395
2415 2396
2416 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2397 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2417 Operand input = ToOperand(instr->value()); 2398 Operand input = ToOperand(instr->value());
2418 2399
2419 int true_block = chunk_->LookupDestination(instr->true_block_id());
2420 int false_block = chunk_->LookupDestination(instr->false_block_id());
2421
2422 __ test(input, Immediate(kSmiTagMask)); 2400 __ test(input, Immediate(kSmiTagMask));
2423 EmitBranch(true_block, false_block, zero); 2401 EmitBranch(instr, zero);
2424 } 2402 }
2425 2403
2426 2404
2427 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2405 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2428 Register input = ToRegister(instr->value()); 2406 Register input = ToRegister(instr->value());
2429 Register temp = ToRegister(instr->temp()); 2407 Register temp = ToRegister(instr->temp());
2430 2408
2431 int true_block = chunk_->LookupDestination(instr->true_block_id());
2432 int false_block = chunk_->LookupDestination(instr->false_block_id());
2433
2434 STATIC_ASSERT(kSmiTag == 0); 2409 STATIC_ASSERT(kSmiTag == 0);
2435 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 2410 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2436 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 2411 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
2437 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 2412 __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
2438 1 << Map::kIsUndetectable); 2413 1 << Map::kIsUndetectable);
2439 EmitBranch(true_block, false_block, not_zero); 2414 EmitBranch(instr, not_zero);
2440 } 2415 }
2441 2416
2442 2417
2443 static Condition ComputeCompareCondition(Token::Value op) { 2418 static Condition ComputeCompareCondition(Token::Value op) {
2444 switch (op) { 2419 switch (op) {
2445 case Token::EQ_STRICT: 2420 case Token::EQ_STRICT:
2446 case Token::EQ: 2421 case Token::EQ:
2447 return equal; 2422 return equal;
2448 case Token::LT: 2423 case Token::LT:
2449 return less; 2424 return less;
2450 case Token::GT: 2425 case Token::GT:
2451 return greater; 2426 return greater;
2452 case Token::LTE: 2427 case Token::LTE:
2453 return less_equal; 2428 return less_equal;
2454 case Token::GTE: 2429 case Token::GTE:
2455 return greater_equal; 2430 return greater_equal;
2456 default: 2431 default:
2457 UNREACHABLE(); 2432 UNREACHABLE();
2458 return no_condition; 2433 return no_condition;
2459 } 2434 }
2460 } 2435 }
2461 2436
2462 2437
2463 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 2438 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2464 Token::Value op = instr->op(); 2439 Token::Value op = instr->op();
2465 int true_block = chunk_->LookupDestination(instr->true_block_id());
2466 int false_block = chunk_->LookupDestination(instr->false_block_id());
2467 2440
2468 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2441 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2469 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2442 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2470 2443
2471 Condition condition = ComputeCompareCondition(op); 2444 Condition condition = ComputeCompareCondition(op);
2472 __ test(eax, Operand(eax)); 2445 __ test(eax, Operand(eax));
2473 2446
2474 EmitBranch(true_block, false_block, condition); 2447 EmitBranch(instr, condition);
2475 } 2448 }
2476 2449
2477 2450
2478 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 2451 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2479 InstanceType from = instr->from(); 2452 InstanceType from = instr->from();
2480 InstanceType to = instr->to(); 2453 InstanceType to = instr->to();
2481 if (from == FIRST_TYPE) return to; 2454 if (from == FIRST_TYPE) return to;
2482 ASSERT(from == to || to == LAST_TYPE); 2455 ASSERT(from == to || to == LAST_TYPE);
2483 return from; 2456 return from;
2484 } 2457 }
2485 2458
2486 2459
2487 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 2460 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2488 InstanceType from = instr->from(); 2461 InstanceType from = instr->from();
2489 InstanceType to = instr->to(); 2462 InstanceType to = instr->to();
2490 if (from == to) return equal; 2463 if (from == to) return equal;
2491 if (to == LAST_TYPE) return above_equal; 2464 if (to == LAST_TYPE) return above_equal;
2492 if (from == FIRST_TYPE) return below_equal; 2465 if (from == FIRST_TYPE) return below_equal;
2493 UNREACHABLE(); 2466 UNREACHABLE();
2494 return equal; 2467 return equal;
2495 } 2468 }
2496 2469
2497 2470
2498 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2471 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2499 Register input = ToRegister(instr->value()); 2472 Register input = ToRegister(instr->value());
2500 Register temp = ToRegister(instr->temp()); 2473 Register temp = ToRegister(instr->temp());
2501 2474
2502 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2475 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2503 int false_block = chunk_->LookupDestination(instr->false_block_id());
2504
2505 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2506
2507 __ JumpIfSmi(input, false_label);
2508 2476
2509 __ CmpObjectType(input, TestType(instr->hydrogen()), temp); 2477 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
2510 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 2478 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2511 } 2479 }
2512 2480
2513 2481
2514 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2482 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2515 Register input = ToRegister(instr->value()); 2483 Register input = ToRegister(instr->value());
2516 Register result = ToRegister(instr->result()); 2484 Register result = ToRegister(instr->result());
2517 2485
2518 __ AssertString(input); 2486 __ AssertString(input);
2519 2487
2520 __ mov(result, FieldOperand(input, String::kHashFieldOffset)); 2488 __ mov(result, FieldOperand(input, String::kHashFieldOffset));
2521 __ IndexFromHash(result, result); 2489 __ IndexFromHash(result, result);
2522 } 2490 }
2523 2491
2524 2492
2525 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2493 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2526 LHasCachedArrayIndexAndBranch* instr) { 2494 LHasCachedArrayIndexAndBranch* instr) {
2527 Register input = ToRegister(instr->value()); 2495 Register input = ToRegister(instr->value());
2528 2496
2529 int true_block = chunk_->LookupDestination(instr->true_block_id());
2530 int false_block = chunk_->LookupDestination(instr->false_block_id());
2531
2532 __ test(FieldOperand(input, String::kHashFieldOffset), 2497 __ test(FieldOperand(input, String::kHashFieldOffset),
2533 Immediate(String::kContainsCachedArrayIndexMask)); 2498 Immediate(String::kContainsCachedArrayIndexMask));
2534 EmitBranch(true_block, false_block, equal); 2499 EmitBranch(instr, equal);
2535 } 2500 }
2536 2501
2537 2502
2538 // Branches to a label or falls through with the answer in the z flag. Trashes 2503 // Branches to a label or falls through with the answer in the z flag. Trashes
2539 // the temp registers, but not the input. 2504 // the temp registers, but not the input.
2540 void LCodeGen::EmitClassOfTest(Label* is_true, 2505 void LCodeGen::EmitClassOfTest(Label* is_true,
2541 Label* is_false, 2506 Label* is_false,
2542 Handle<String>class_name, 2507 Handle<String>class_name,
2543 Register input, 2508 Register input,
2544 Register temp, 2509 Register temp,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2600 } 2565 }
2601 2566
2602 2567
2603 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2568 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2604 Register input = ToRegister(instr->value()); 2569 Register input = ToRegister(instr->value());
2605 Register temp = ToRegister(instr->temp()); 2570 Register temp = ToRegister(instr->temp());
2606 Register temp2 = ToRegister(instr->temp2()); 2571 Register temp2 = ToRegister(instr->temp2());
2607 2572
2608 Handle<String> class_name = instr->hydrogen()->class_name(); 2573 Handle<String> class_name = instr->hydrogen()->class_name();
2609 2574
2610 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2575 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2611 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2576 class_name, input, temp, temp2);
2612 2577
2613 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2578 EmitBranch(instr, equal);
2614 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2615
2616 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2617
2618 EmitBranch(true_block, false_block, equal);
2619 } 2579 }
2620 2580
2621 2581
2622 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2582 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2623 Register reg = ToRegister(instr->value()); 2583 Register reg = ToRegister(instr->value());
2624 int true_block = instr->true_block_id();
2625 int false_block = instr->false_block_id();
2626
2627 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 2584 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2628 EmitBranch(true_block, false_block, equal); 2585 EmitBranch(instr, equal);
2629 } 2586 }
2630 2587
2631 2588
2632 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2589 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2633 // Object and function are in fixed registers defined by the stub. 2590 // Object and function are in fixed registers defined by the stub.
2634 ASSERT(ToRegister(instr->context()).is(esi)); 2591 ASSERT(ToRegister(instr->context()).is(esi));
2635 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 2592 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
2636 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2593 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2637 2594
2638 Label true_value, done; 2595 Label true_value, done;
(...skipping 3597 matching lines...) Expand 10 before | Expand all | Expand 10 after
6236 6193
6237 void LCodeGen::DoTypeof(LTypeof* instr) { 6194 void LCodeGen::DoTypeof(LTypeof* instr) {
6238 LOperand* input = instr->value(); 6195 LOperand* input = instr->value();
6239 EmitPushTaggedOperand(input); 6196 EmitPushTaggedOperand(input);
6240 CallRuntime(Runtime::kTypeof, 1, instr); 6197 CallRuntime(Runtime::kTypeof, 1, instr);
6241 } 6198 }
6242 6199
6243 6200
6244 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 6201 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
6245 Register input = ToRegister(instr->value()); 6202 Register input = ToRegister(instr->value());
6246 int true_block = chunk_->LookupDestination(instr->true_block_id());
6247 int false_block = chunk_->LookupDestination(instr->false_block_id());
6248 Label* true_label = chunk_->GetAssemblyLabel(true_block);
6249 Label* false_label = chunk_->GetAssemblyLabel(false_block);
6250 6203
6251 Condition final_branch_condition = 6204 Condition final_branch_condition =
6252 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); 6205 EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
6206 input, instr->type_literal());
6253 if (final_branch_condition != no_condition) { 6207 if (final_branch_condition != no_condition) {
6254 EmitBranch(true_block, false_block, final_branch_condition); 6208 EmitBranch(instr, final_branch_condition);
6255 } 6209 }
6256 } 6210 }
6257 6211
6258 6212
6259 Condition LCodeGen::EmitTypeofIs(Label* true_label, 6213 Condition LCodeGen::EmitTypeofIs(Label* true_label,
6260 Label* false_label, 6214 Label* false_label,
6261 Register input, 6215 Register input,
6262 Handle<String> type_name) { 6216 Handle<String> type_name) {
6263 Condition final_branch_condition = no_condition; 6217 Condition final_branch_condition = no_condition;
6264 if (type_name->Equals(heap()->number_string())) { 6218 if (type_name->Equals(heap()->number_string())) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
6325 6279
6326 } else { 6280 } else {
6327 __ jmp(false_label); 6281 __ jmp(false_label);
6328 } 6282 }
6329 return final_branch_condition; 6283 return final_branch_condition;
6330 } 6284 }
6331 6285
6332 6286
6333 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 6287 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
6334 Register temp = ToRegister(instr->temp()); 6288 Register temp = ToRegister(instr->temp());
6335 int true_block = chunk_->LookupDestination(instr->true_block_id());
6336 int false_block = chunk_->LookupDestination(instr->false_block_id());
6337 6289
6338 EmitIsConstructCall(temp); 6290 EmitIsConstructCall(temp);
6339 EmitBranch(true_block, false_block, equal); 6291 EmitBranch(instr, equal);
6340 } 6292 }
6341 6293
6342 6294
6343 void LCodeGen::EmitIsConstructCall(Register temp) { 6295 void LCodeGen::EmitIsConstructCall(Register temp) {
6344 // Get the frame pointer for the calling frame. 6296 // Get the frame pointer for the calling frame.
6345 __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 6297 __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
6346 6298
6347 // Skip the arguments adaptor frame if it exists. 6299 // Skip the arguments adaptor frame if it exists.
6348 Label check_frame_marker; 6300 Label check_frame_marker;
6349 __ cmp(Operand(temp, StandardFrameConstants::kContextOffset), 6301 __ cmp(Operand(temp, StandardFrameConstants::kContextOffset),
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
6593 FixedArray::kHeaderSize - kPointerSize)); 6545 FixedArray::kHeaderSize - kPointerSize));
6594 __ bind(&done); 6546 __ bind(&done);
6595 } 6547 }
6596 6548
6597 6549
6598 #undef __ 6550 #undef __
6599 6551
6600 } } // namespace v8::internal 6552 } } // namespace v8::internal
6601 6553
6602 #endif // V8_TARGET_ARCH_IA32 6554 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698