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

Side by Side Diff: src/arm/lithium-codegen-arm.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/arm/lithium-codegen-arm.h ('k') | src/ia32/lithium-codegen-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 2141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2152 } 2152 }
2153 2153
2154 2154
2155 int LCodeGen::GetNextEmittedBlock() const { 2155 int LCodeGen::GetNextEmittedBlock() const {
2156 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 2156 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
2157 if (!chunk_->GetLabel(i)->HasReplacement()) return i; 2157 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
2158 } 2158 }
2159 return -1; 2159 return -1;
2160 } 2160 }
2161 2161
2162 template<class InstrType>
2163 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
2164 int right_block = instr->FalseDestination(chunk_);
2165 int left_block = instr->TrueDestination(chunk_);
2162 2166
2163 void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) {
2164 int next_block = GetNextEmittedBlock(); 2167 int next_block = GetNextEmittedBlock();
2165 right_block = chunk_->LookupDestination(right_block);
2166 left_block = chunk_->LookupDestination(left_block);
2167 2168
2168 if (right_block == left_block) { 2169 if (right_block == left_block) {
2169 EmitGoto(left_block); 2170 EmitGoto(left_block);
2170 } else if (left_block == next_block) { 2171 } else if (left_block == next_block) {
2171 __ b(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block)); 2172 __ b(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block));
2172 } else if (right_block == next_block) { 2173 } else if (right_block == next_block) {
2173 __ b(cc, chunk_->GetAssemblyLabel(left_block)); 2174 __ b(cc, chunk_->GetAssemblyLabel(left_block));
2174 } else { 2175 } else {
2175 __ b(cc, chunk_->GetAssemblyLabel(left_block)); 2176 __ b(cc, chunk_->GetAssemblyLabel(left_block));
2176 __ b(chunk_->GetAssemblyLabel(right_block)); 2177 __ b(chunk_->GetAssemblyLabel(right_block));
2177 } 2178 }
2178 } 2179 }
2179 2180
2180 2181
2181 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 2182 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
2182 __ stop("LBreak"); 2183 __ stop("LBreak");
2183 } 2184 }
2184 2185
2185 2186
2186 void LCodeGen::DoBranch(LBranch* instr) { 2187 void LCodeGen::DoBranch(LBranch* instr) {
2187 int true_block = chunk_->LookupDestination(instr->true_block_id());
2188 int false_block = chunk_->LookupDestination(instr->false_block_id());
2189
2190 Representation r = instr->hydrogen()->value()->representation(); 2188 Representation r = instr->hydrogen()->value()->representation();
2191 if (r.IsInteger32() || r.IsSmi()) { 2189 if (r.IsInteger32() || r.IsSmi()) {
2192 ASSERT(!info()->IsStub()); 2190 ASSERT(!info()->IsStub());
2193 Register reg = ToRegister(instr->value()); 2191 Register reg = ToRegister(instr->value());
2194 __ cmp(reg, Operand::Zero()); 2192 __ cmp(reg, Operand::Zero());
2195 EmitBranch(true_block, false_block, ne); 2193 EmitBranch(instr, ne);
2196 } else if (r.IsDouble()) { 2194 } else if (r.IsDouble()) {
2197 ASSERT(!info()->IsStub()); 2195 ASSERT(!info()->IsStub());
2198 DwVfpRegister reg = ToDoubleRegister(instr->value()); 2196 DwVfpRegister reg = ToDoubleRegister(instr->value());
2199 // Test the double value. Zero and NaN are false. 2197 // Test the double value. Zero and NaN are false.
2200 __ VFPCompareAndSetFlags(reg, 0.0); 2198 __ VFPCompareAndSetFlags(reg, 0.0);
2201 __ cmp(r0, r0, vs); // If NaN, set the Z flag. 2199 __ cmp(r0, r0, vs); // If NaN, set the Z flag.
2202 EmitBranch(true_block, false_block, ne); 2200 EmitBranch(instr, ne);
2203 } else { 2201 } else {
2204 ASSERT(r.IsTagged()); 2202 ASSERT(r.IsTagged());
2205 Register reg = ToRegister(instr->value()); 2203 Register reg = ToRegister(instr->value());
2206 HType type = instr->hydrogen()->value()->type(); 2204 HType type = instr->hydrogen()->value()->type();
2207 if (type.IsBoolean()) { 2205 if (type.IsBoolean()) {
2208 ASSERT(!info()->IsStub()); 2206 ASSERT(!info()->IsStub());
2209 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 2207 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
2210 EmitBranch(true_block, false_block, eq); 2208 EmitBranch(instr, eq);
2211 } else if (type.IsSmi()) { 2209 } else if (type.IsSmi()) {
2212 ASSERT(!info()->IsStub()); 2210 ASSERT(!info()->IsStub());
2213 __ cmp(reg, Operand::Zero()); 2211 __ cmp(reg, Operand::Zero());
2214 EmitBranch(true_block, false_block, ne); 2212 EmitBranch(instr, ne);
2215 } else { 2213 } else {
2216 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2217 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2218
2219 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 2214 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2220 // Avoid deopts in the case where we've never executed this path before. 2215 // Avoid deopts in the case where we've never executed this path before.
2221 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 2216 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
2222 2217
2223 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 2218 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
2224 // undefined -> false. 2219 // undefined -> false.
2225 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); 2220 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
2226 __ b(eq, false_label); 2221 __ b(eq, instr->FalseLabel(chunk_));
2227 } 2222 }
2228 if (expected.Contains(ToBooleanStub::BOOLEAN)) { 2223 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
2229 // Boolean -> its value. 2224 // Boolean -> its value.
2230 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 2225 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
2231 __ b(eq, true_label); 2226 __ b(eq, instr->TrueLabel(chunk_));
2232 __ CompareRoot(reg, Heap::kFalseValueRootIndex); 2227 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
2233 __ b(eq, false_label); 2228 __ b(eq, instr->FalseLabel(chunk_));
2234 } 2229 }
2235 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 2230 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
2236 // 'null' -> false. 2231 // 'null' -> false.
2237 __ CompareRoot(reg, Heap::kNullValueRootIndex); 2232 __ CompareRoot(reg, Heap::kNullValueRootIndex);
2238 __ b(eq, false_label); 2233 __ b(eq, instr->FalseLabel(chunk_));
2239 } 2234 }
2240 2235
2241 if (expected.Contains(ToBooleanStub::SMI)) { 2236 if (expected.Contains(ToBooleanStub::SMI)) {
2242 // Smis: 0 -> false, all other -> true. 2237 // Smis: 0 -> false, all other -> true.
2243 __ cmp(reg, Operand::Zero()); 2238 __ cmp(reg, Operand::Zero());
2244 __ b(eq, false_label); 2239 __ b(eq, instr->FalseLabel(chunk_));
2245 __ JumpIfSmi(reg, true_label); 2240 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2246 } else if (expected.NeedsMap()) { 2241 } else if (expected.NeedsMap()) {
2247 // If we need a map later and have a Smi -> deopt. 2242 // If we need a map later and have a Smi -> deopt.
2248 __ SmiTst(reg); 2243 __ SmiTst(reg);
2249 DeoptimizeIf(eq, instr->environment()); 2244 DeoptimizeIf(eq, instr->environment());
2250 } 2245 }
2251 2246
2252 const Register map = scratch0(); 2247 const Register map = scratch0();
2253 if (expected.NeedsMap()) { 2248 if (expected.NeedsMap()) {
2254 __ ldr(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 2249 __ ldr(map, FieldMemOperand(reg, HeapObject::kMapOffset));
2255 2250
2256 if (expected.CanBeUndetectable()) { 2251 if (expected.CanBeUndetectable()) {
2257 // Undetectable -> false. 2252 // Undetectable -> false.
2258 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); 2253 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset));
2259 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 2254 __ tst(ip, Operand(1 << Map::kIsUndetectable));
2260 __ b(ne, false_label); 2255 __ b(ne, instr->FalseLabel(chunk_));
2261 } 2256 }
2262 } 2257 }
2263 2258
2264 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 2259 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
2265 // spec object -> true. 2260 // spec object -> true.
2266 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); 2261 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
2267 __ b(ge, true_label); 2262 __ b(ge, instr->TrueLabel(chunk_));
2268 } 2263 }
2269 2264
2270 if (expected.Contains(ToBooleanStub::STRING)) { 2265 if (expected.Contains(ToBooleanStub::STRING)) {
2271 // String value -> false iff empty. 2266 // String value -> false iff empty.
2272 Label not_string; 2267 Label not_string;
2273 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); 2268 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
2274 __ b(ge, &not_string); 2269 __ b(ge, &not_string);
2275 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); 2270 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset));
2276 __ cmp(ip, Operand::Zero()); 2271 __ cmp(ip, Operand::Zero());
2277 __ b(ne, true_label); 2272 __ b(ne, instr->TrueLabel(chunk_));
2278 __ b(false_label); 2273 __ b(instr->FalseLabel(chunk_));
2279 __ bind(&not_string); 2274 __ bind(&not_string);
2280 } 2275 }
2281 2276
2282 if (expected.Contains(ToBooleanStub::SYMBOL)) { 2277 if (expected.Contains(ToBooleanStub::SYMBOL)) {
2283 // Symbol value -> true. 2278 // Symbol value -> true.
2284 __ CompareInstanceType(map, ip, SYMBOL_TYPE); 2279 __ CompareInstanceType(map, ip, SYMBOL_TYPE);
2285 __ b(eq, true_label); 2280 __ b(eq, instr->TrueLabel(chunk_));
2286 } 2281 }
2287 2282
2288 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2283 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2289 // heap number -> false iff +0, -0, or NaN. 2284 // heap number -> false iff +0, -0, or NaN.
2290 DwVfpRegister dbl_scratch = double_scratch0(); 2285 DwVfpRegister dbl_scratch = double_scratch0();
2291 Label not_heap_number; 2286 Label not_heap_number;
2292 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 2287 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
2293 __ b(ne, &not_heap_number); 2288 __ b(ne, &not_heap_number);
2294 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 2289 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
2295 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); 2290 __ VFPCompareAndSetFlags(dbl_scratch, 0.0);
2296 __ cmp(r0, r0, vs); // NaN -> false. 2291 __ cmp(r0, r0, vs); // NaN -> false.
2297 __ b(eq, false_label); // +0, -0 -> false. 2292 __ b(eq, instr->FalseLabel(chunk_)); // +0, -0 -> false.
2298 __ b(true_label); 2293 __ b(instr->TrueLabel(chunk_));
2299 __ bind(&not_heap_number); 2294 __ bind(&not_heap_number);
2300 } 2295 }
2301 2296
2302 // We've seen something for the first time -> deopt. 2297 // We've seen something for the first time -> deopt.
2303 DeoptimizeIf(al, instr->environment()); 2298 DeoptimizeIf(al, instr->environment());
2304 } 2299 }
2305 } 2300 }
2306 } 2301 }
2307 2302
2308 2303
2309 void LCodeGen::EmitGoto(int block) { 2304 void LCodeGen::EmitGoto(int block) {
2310 if (!IsNextEmittedBlock(block)) { 2305 if (!IsNextEmittedBlock(block)) {
2311 __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); 2306 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
2312 } 2307 }
2313 } 2308 }
2314 2309
2315 2310
2316 void LCodeGen::DoGoto(LGoto* instr) { 2311 void LCodeGen::DoGoto(LGoto* instr) {
2317 EmitGoto(instr->block_id()); 2312 EmitGoto(instr->block_id());
2318 } 2313 }
2319 2314
2320 2315
2321 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2316 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
(...skipping 20 matching lines...) Expand all
2342 default: 2337 default:
2343 UNREACHABLE(); 2338 UNREACHABLE();
2344 } 2339 }
2345 return cond; 2340 return cond;
2346 } 2341 }
2347 2342
2348 2343
2349 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 2344 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
2350 LOperand* left = instr->left(); 2345 LOperand* left = instr->left();
2351 LOperand* right = instr->right(); 2346 LOperand* right = instr->right();
2352 int false_block = chunk_->LookupDestination(instr->false_block_id());
2353 int true_block = chunk_->LookupDestination(instr->true_block_id());
2354 Condition cond = TokenToCondition(instr->op(), false); 2347 Condition cond = TokenToCondition(instr->op(), false);
2355 2348
2356 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2349 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2357 // We can statically evaluate the comparison. 2350 // We can statically evaluate the comparison.
2358 double left_val = ToDouble(LConstantOperand::cast(left)); 2351 double left_val = ToDouble(LConstantOperand::cast(left));
2359 double right_val = ToDouble(LConstantOperand::cast(right)); 2352 double right_val = ToDouble(LConstantOperand::cast(right));
2360 int next_block = 2353 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2361 EvalComparison(instr->op(), left_val, right_val) ? true_block 2354 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2362 : false_block;
2363 EmitGoto(next_block); 2355 EmitGoto(next_block);
2364 } else { 2356 } else {
2365 if (instr->is_double()) { 2357 if (instr->is_double()) {
2366 // Compare left and right operands as doubles and load the 2358 // Compare left and right operands as doubles and load the
2367 // resulting flags into the normal status register. 2359 // resulting flags into the normal status register.
2368 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); 2360 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right));
2369 // If a NaN is involved, i.e. the result is unordered (V set), 2361 // If a NaN is involved, i.e. the result is unordered (V set),
2370 // jump to false block label. 2362 // jump to false block label.
2371 __ b(vs, chunk_->GetAssemblyLabel(false_block)); 2363 __ b(vs, instr->FalseLabel(chunk_));
2372 } else { 2364 } else {
2373 if (right->IsConstantOperand()) { 2365 if (right->IsConstantOperand()) {
2374 int32_t value = ToInteger32(LConstantOperand::cast(right)); 2366 int32_t value = ToInteger32(LConstantOperand::cast(right));
2375 if (instr->hydrogen_value()->representation().IsSmi()) { 2367 if (instr->hydrogen_value()->representation().IsSmi()) {
2376 __ cmp(ToRegister(left), Operand(Smi::FromInt(value))); 2368 __ cmp(ToRegister(left), Operand(Smi::FromInt(value)));
2377 } else { 2369 } else {
2378 __ cmp(ToRegister(left), Operand(value)); 2370 __ cmp(ToRegister(left), Operand(value));
2379 } 2371 }
2380 } else if (left->IsConstantOperand()) { 2372 } else if (left->IsConstantOperand()) {
2381 int32_t value = ToInteger32(LConstantOperand::cast(left)); 2373 int32_t value = ToInteger32(LConstantOperand::cast(left));
2382 if (instr->hydrogen_value()->representation().IsSmi()) { 2374 if (instr->hydrogen_value()->representation().IsSmi()) {
2383 __ cmp(ToRegister(right), Operand(Smi::FromInt(value))); 2375 __ cmp(ToRegister(right), Operand(Smi::FromInt(value)));
2384 } else { 2376 } else {
2385 __ cmp(ToRegister(right), Operand(value)); 2377 __ cmp(ToRegister(right), Operand(value));
2386 } 2378 }
2387 // We transposed the operands. Reverse the condition. 2379 // We transposed the operands. Reverse the condition.
2388 cond = ReverseCondition(cond); 2380 cond = ReverseCondition(cond);
2389 } else { 2381 } else {
2390 __ cmp(ToRegister(left), ToRegister(right)); 2382 __ cmp(ToRegister(left), ToRegister(right));
2391 } 2383 }
2392 } 2384 }
2393 EmitBranch(true_block, false_block, cond); 2385 EmitBranch(instr, cond);
2394 } 2386 }
2395 } 2387 }
2396 2388
2397 2389
2398 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2390 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2399 Register left = ToRegister(instr->left()); 2391 Register left = ToRegister(instr->left());
2400 Register right = ToRegister(instr->right()); 2392 Register right = ToRegister(instr->right());
2401 int false_block = chunk_->LookupDestination(instr->false_block_id());
2402 int true_block = chunk_->LookupDestination(instr->true_block_id());
2403 2393
2404 __ cmp(left, Operand(right)); 2394 __ cmp(left, Operand(right));
2405 EmitBranch(true_block, false_block, eq); 2395 EmitBranch(instr, eq);
2406 } 2396 }
2407 2397
2408 2398
2409 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 2399 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
2410 Register left = ToRegister(instr->left()); 2400 Register left = ToRegister(instr->left());
2411 int true_block = chunk_->LookupDestination(instr->true_block_id());
2412 int false_block = chunk_->LookupDestination(instr->false_block_id());
2413 2401
2414 __ cmp(left, Operand(instr->hydrogen()->right())); 2402 __ cmp(left, Operand(instr->hydrogen()->right()));
2415 EmitBranch(true_block, false_block, eq); 2403 EmitBranch(instr, eq);
2416 } 2404 }
2417 2405
2418 2406
2419 Condition LCodeGen::EmitIsObject(Register input, 2407 Condition LCodeGen::EmitIsObject(Register input,
2420 Register temp1, 2408 Register temp1,
2421 Label* is_not_object, 2409 Label* is_not_object,
2422 Label* is_object) { 2410 Label* is_object) {
2423 Register temp2 = scratch0(); 2411 Register temp2 = scratch0();
2424 __ JumpIfSmi(input, is_not_object); 2412 __ JumpIfSmi(input, is_not_object);
2425 2413
(...skipping 14 matching lines...) Expand all
2440 __ b(lt, is_not_object); 2428 __ b(lt, is_not_object);
2441 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2429 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
2442 return le; 2430 return le;
2443 } 2431 }
2444 2432
2445 2433
2446 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 2434 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2447 Register reg = ToRegister(instr->value()); 2435 Register reg = ToRegister(instr->value());
2448 Register temp1 = ToRegister(instr->temp()); 2436 Register temp1 = ToRegister(instr->temp());
2449 2437
2450 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2438 Condition true_cond =
2451 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2439 EmitIsObject(reg, temp1,
2452 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2440 instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2453 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2454 2441
2455 Condition true_cond = 2442 EmitBranch(instr, true_cond);
2456 EmitIsObject(reg, temp1, false_label, true_label);
2457
2458 EmitBranch(true_block, false_block, true_cond);
2459 } 2443 }
2460 2444
2461 2445
2462 Condition LCodeGen::EmitIsString(Register input, 2446 Condition LCodeGen::EmitIsString(Register input,
2463 Register temp1, 2447 Register temp1,
2464 Label* is_not_string) { 2448 Label* is_not_string) {
2465 __ JumpIfSmi(input, is_not_string); 2449 __ JumpIfSmi(input, is_not_string);
2466 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE); 2450 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE);
2467 2451
2468 return lt; 2452 return lt;
2469 } 2453 }
2470 2454
2471 2455
2472 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2456 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2473 Register reg = ToRegister(instr->value()); 2457 Register reg = ToRegister(instr->value());
2474 Register temp1 = ToRegister(instr->temp()); 2458 Register temp1 = ToRegister(instr->temp());
2475 2459
2476 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2460 Condition true_cond =
2477 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2461 EmitIsString(reg, temp1, instr->FalseLabel(chunk_));
2478 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2479 2462
2480 Condition true_cond = 2463 EmitBranch(instr, true_cond);
2481 EmitIsString(reg, temp1, false_label);
2482
2483 EmitBranch(true_block, false_block, true_cond);
2484 } 2464 }
2485 2465
2486 2466
2487 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2467 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2488 int true_block = chunk_->LookupDestination(instr->true_block_id());
2489 int false_block = chunk_->LookupDestination(instr->false_block_id());
2490
2491 Register input_reg = EmitLoadRegister(instr->value(), ip); 2468 Register input_reg = EmitLoadRegister(instr->value(), ip);
2492 __ SmiTst(input_reg); 2469 __ SmiTst(input_reg);
2493 EmitBranch(true_block, false_block, eq); 2470 EmitBranch(instr, eq);
2494 } 2471 }
2495 2472
2496 2473
2497 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2474 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2498 Register input = ToRegister(instr->value()); 2475 Register input = ToRegister(instr->value());
2499 Register temp = ToRegister(instr->temp()); 2476 Register temp = ToRegister(instr->temp());
2500 2477
2501 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2478 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2502 int false_block = chunk_->LookupDestination(instr->false_block_id());
2503
2504 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
2505 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); 2479 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset));
2506 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); 2480 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
2507 __ tst(temp, Operand(1 << Map::kIsUndetectable)); 2481 __ tst(temp, Operand(1 << Map::kIsUndetectable));
2508 EmitBranch(true_block, false_block, ne); 2482 EmitBranch(instr, ne);
2509 } 2483 }
2510 2484
2511 2485
2512 static Condition ComputeCompareCondition(Token::Value op) { 2486 static Condition ComputeCompareCondition(Token::Value op) {
2513 switch (op) { 2487 switch (op) {
2514 case Token::EQ_STRICT: 2488 case Token::EQ_STRICT:
2515 case Token::EQ: 2489 case Token::EQ:
2516 return eq; 2490 return eq;
2517 case Token::LT: 2491 case Token::LT:
2518 return lt; 2492 return lt;
2519 case Token::GT: 2493 case Token::GT:
2520 return gt; 2494 return gt;
2521 case Token::LTE: 2495 case Token::LTE:
2522 return le; 2496 return le;
2523 case Token::GTE: 2497 case Token::GTE:
2524 return ge; 2498 return ge;
2525 default: 2499 default:
2526 UNREACHABLE(); 2500 UNREACHABLE();
2527 return kNoCondition; 2501 return kNoCondition;
2528 } 2502 }
2529 } 2503 }
2530 2504
2531 2505
2532 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 2506 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2533 Token::Value op = instr->op(); 2507 Token::Value op = instr->op();
2534 int true_block = chunk_->LookupDestination(instr->true_block_id());
2535 int false_block = chunk_->LookupDestination(instr->false_block_id());
2536 2508
2537 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2509 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2538 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2510 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2539 // This instruction also signals no smi code inlined. 2511 // This instruction also signals no smi code inlined.
2540 __ cmp(r0, Operand::Zero()); 2512 __ cmp(r0, Operand::Zero());
2541 2513
2542 Condition condition = ComputeCompareCondition(op); 2514 Condition condition = ComputeCompareCondition(op);
2543 2515
2544 EmitBranch(true_block, false_block, condition); 2516 EmitBranch(instr, condition);
2545 } 2517 }
2546 2518
2547 2519
2548 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 2520 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2549 InstanceType from = instr->from(); 2521 InstanceType from = instr->from();
2550 InstanceType to = instr->to(); 2522 InstanceType to = instr->to();
2551 if (from == FIRST_TYPE) return to; 2523 if (from == FIRST_TYPE) return to;
2552 ASSERT(from == to || to == LAST_TYPE); 2524 ASSERT(from == to || to == LAST_TYPE);
2553 return from; 2525 return from;
2554 } 2526 }
2555 2527
2556 2528
2557 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 2529 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2558 InstanceType from = instr->from(); 2530 InstanceType from = instr->from();
2559 InstanceType to = instr->to(); 2531 InstanceType to = instr->to();
2560 if (from == to) return eq; 2532 if (from == to) return eq;
2561 if (to == LAST_TYPE) return hs; 2533 if (to == LAST_TYPE) return hs;
2562 if (from == FIRST_TYPE) return ls; 2534 if (from == FIRST_TYPE) return ls;
2563 UNREACHABLE(); 2535 UNREACHABLE();
2564 return eq; 2536 return eq;
2565 } 2537 }
2566 2538
2567 2539
2568 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2540 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2569 Register scratch = scratch0(); 2541 Register scratch = scratch0();
2570 Register input = ToRegister(instr->value()); 2542 Register input = ToRegister(instr->value());
2571 2543
2572 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2544 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2573 int false_block = chunk_->LookupDestination(instr->false_block_id());
2574
2575 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2576
2577 __ JumpIfSmi(input, false_label);
2578 2545
2579 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); 2546 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
2580 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 2547 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2581 } 2548 }
2582 2549
2583 2550
2584 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2551 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2585 Register input = ToRegister(instr->value()); 2552 Register input = ToRegister(instr->value());
2586 Register result = ToRegister(instr->result()); 2553 Register result = ToRegister(instr->result());
2587 2554
2588 __ AssertString(input); 2555 __ AssertString(input);
2589 2556
2590 __ ldr(result, FieldMemOperand(input, String::kHashFieldOffset)); 2557 __ ldr(result, FieldMemOperand(input, String::kHashFieldOffset));
2591 __ IndexFromHash(result, result); 2558 __ IndexFromHash(result, result);
2592 } 2559 }
2593 2560
2594 2561
2595 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2562 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2596 LHasCachedArrayIndexAndBranch* instr) { 2563 LHasCachedArrayIndexAndBranch* instr) {
2597 Register input = ToRegister(instr->value()); 2564 Register input = ToRegister(instr->value());
2598 Register scratch = scratch0(); 2565 Register scratch = scratch0();
2599 2566
2600 int true_block = chunk_->LookupDestination(instr->true_block_id());
2601 int false_block = chunk_->LookupDestination(instr->false_block_id());
2602
2603 __ ldr(scratch, 2567 __ ldr(scratch,
2604 FieldMemOperand(input, String::kHashFieldOffset)); 2568 FieldMemOperand(input, String::kHashFieldOffset));
2605 __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask)); 2569 __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask));
2606 EmitBranch(true_block, false_block, eq); 2570 EmitBranch(instr, eq);
2607 } 2571 }
2608 2572
2609 2573
2610 // Branches to a label or falls through with the answer in flags. Trashes 2574 // Branches to a label or falls through with the answer in flags. Trashes
2611 // the temp registers, but not the input. 2575 // the temp registers, but not the input.
2612 void LCodeGen::EmitClassOfTest(Label* is_true, 2576 void LCodeGen::EmitClassOfTest(Label* is_true,
2613 Label* is_false, 2577 Label* is_false,
2614 Handle<String>class_name, 2578 Handle<String>class_name,
2615 Register input, 2579 Register input,
2616 Register temp, 2580 Register temp,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2673 // End with the answer in flags. 2637 // End with the answer in flags.
2674 } 2638 }
2675 2639
2676 2640
2677 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2641 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2678 Register input = ToRegister(instr->value()); 2642 Register input = ToRegister(instr->value());
2679 Register temp = scratch0(); 2643 Register temp = scratch0();
2680 Register temp2 = ToRegister(instr->temp()); 2644 Register temp2 = ToRegister(instr->temp());
2681 Handle<String> class_name = instr->hydrogen()->class_name(); 2645 Handle<String> class_name = instr->hydrogen()->class_name();
2682 2646
2683 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2647 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2684 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2648 class_name, input, temp, temp2);
2685 2649
2686 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2650 EmitBranch(instr, eq);
2687 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2688
2689 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2690
2691 EmitBranch(true_block, false_block, eq);
2692 } 2651 }
2693 2652
2694 2653
2695 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2654 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2696 Register reg = ToRegister(instr->value()); 2655 Register reg = ToRegister(instr->value());
2697 Register temp = ToRegister(instr->temp()); 2656 Register temp = ToRegister(instr->temp());
2698 int true_block = instr->true_block_id();
2699 int false_block = instr->false_block_id();
2700 2657
2701 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 2658 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
2702 __ cmp(temp, Operand(instr->map())); 2659 __ cmp(temp, Operand(instr->map()));
2703 EmitBranch(true_block, false_block, eq); 2660 EmitBranch(instr, eq);
2704 } 2661 }
2705 2662
2706 2663
2707 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2664 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2708 ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0. 2665 ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0.
2709 ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1. 2666 ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1.
2710 2667
2711 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 2668 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
2712 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2669 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2713 2670
(...skipping 2876 matching lines...) Expand 10 before | Expand all | Expand 10 after
5590 5547
5591 void LCodeGen::DoTypeof(LTypeof* instr) { 5548 void LCodeGen::DoTypeof(LTypeof* instr) {
5592 Register input = ToRegister(instr->value()); 5549 Register input = ToRegister(instr->value());
5593 __ push(input); 5550 __ push(input);
5594 CallRuntime(Runtime::kTypeof, 1, instr); 5551 CallRuntime(Runtime::kTypeof, 1, instr);
5595 } 5552 }
5596 5553
5597 5554
5598 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5555 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5599 Register input = ToRegister(instr->value()); 5556 Register input = ToRegister(instr->value());
5600 int true_block = chunk_->LookupDestination(instr->true_block_id());
5601 int false_block = chunk_->LookupDestination(instr->false_block_id());
5602 Label* true_label = chunk_->GetAssemblyLabel(true_block);
5603 Label* false_label = chunk_->GetAssemblyLabel(false_block);
5604 5557
5605 Condition final_branch_condition = EmitTypeofIs(true_label, 5558 Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_),
5606 false_label, 5559 instr->FalseLabel(chunk_),
5607 input, 5560 input,
5608 instr->type_literal()); 5561 instr->type_literal());
5609 if (final_branch_condition != kNoCondition) { 5562 if (final_branch_condition != kNoCondition) {
5610 EmitBranch(true_block, false_block, final_branch_condition); 5563 EmitBranch(instr, final_branch_condition);
5611 } 5564 }
5612 } 5565 }
5613 5566
5614 5567
5615 Condition LCodeGen::EmitTypeofIs(Label* true_label, 5568 Condition LCodeGen::EmitTypeofIs(Label* true_label,
5616 Label* false_label, 5569 Label* false_label,
5617 Register input, 5570 Register input,
5618 Handle<String> type_name) { 5571 Handle<String> type_name) {
5619 Condition final_branch_condition = kNoCondition; 5572 Condition final_branch_condition = kNoCondition;
5620 Register scratch = scratch0(); 5573 Register scratch = scratch0();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
5685 } else { 5638 } else {
5686 __ b(false_label); 5639 __ b(false_label);
5687 } 5640 }
5688 5641
5689 return final_branch_condition; 5642 return final_branch_condition;
5690 } 5643 }
5691 5644
5692 5645
5693 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5646 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5694 Register temp1 = ToRegister(instr->temp()); 5647 Register temp1 = ToRegister(instr->temp());
5695 int true_block = chunk_->LookupDestination(instr->true_block_id());
5696 int false_block = chunk_->LookupDestination(instr->false_block_id());
5697 5648
5698 EmitIsConstructCall(temp1, scratch0()); 5649 EmitIsConstructCall(temp1, scratch0());
5699 EmitBranch(true_block, false_block, eq); 5650 EmitBranch(instr, eq);
5700 } 5651 }
5701 5652
5702 5653
5703 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { 5654 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
5704 ASSERT(!temp1.is(temp2)); 5655 ASSERT(!temp1.is(temp2));
5705 // Get the frame pointer for the calling frame. 5656 // Get the frame pointer for the calling frame.
5706 __ ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 5657 __ ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
5707 5658
5708 // Skip the arguments adaptor frame if it exists. 5659 // Skip the arguments adaptor frame if it exists.
5709 Label check_frame_marker; 5660 Label check_frame_marker;
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
5954 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5905 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5955 __ ldr(result, FieldMemOperand(scratch, 5906 __ ldr(result, FieldMemOperand(scratch,
5956 FixedArray::kHeaderSize - kPointerSize)); 5907 FixedArray::kHeaderSize - kPointerSize));
5957 __ bind(&done); 5908 __ bind(&done);
5958 } 5909 }
5959 5910
5960 5911
5961 #undef __ 5912 #undef __
5962 5913
5963 } } // namespace v8::internal 5914 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698