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

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

Issue 23618002: Hydrogenisation of binops (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 7 years, 3 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/full-codegen-ia32.cc ('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 1715 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 break; 1726 break;
1727 case 5: 1727 case 5:
1728 __ lea(left, Operand(left, left, times_4, 0)); 1728 __ lea(left, Operand(left, left, times_4, 0));
1729 break; 1729 break;
1730 case 8: 1730 case 8:
1731 __ shl(left, 3); 1731 __ shl(left, 3);
1732 break; 1732 break;
1733 case 9: 1733 case 9:
1734 __ lea(left, Operand(left, left, times_8, 0)); 1734 __ lea(left, Operand(left, left, times_8, 0));
1735 break; 1735 break;
1736 case 16: 1736 case 16:
1737 __ shl(left, 4); 1737 __ shl(left, 4);
1738 break; 1738 break;
1739 default: 1739 default:
1740 __ imul(left, left, constant); 1740 __ imul(left, left, constant);
1741 break; 1741 break;
1742 } 1742 }
1743 } else { 1743 } else {
1744 __ imul(left, left, constant); 1744 __ imul(left, left, constant);
1745 } 1745 }
1746 } else { 1746 } else {
1747 if (instr->hydrogen()->representation().IsSmi()) { 1747 if (instr->hydrogen()->representation().IsSmi()) {
1748 __ SmiUntag(left); 1748 __ SmiUntag(left);
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2201 } 2201 }
2202 } 2202 }
2203 2203
2204 2204
2205 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 2205 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
2206 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2206 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
2207 CpuFeatureScope scope(masm(), SSE2); 2207 CpuFeatureScope scope(masm(), SSE2);
2208 XMMRegister left = ToDoubleRegister(instr->left()); 2208 XMMRegister left = ToDoubleRegister(instr->left());
2209 XMMRegister right = ToDoubleRegister(instr->right()); 2209 XMMRegister right = ToDoubleRegister(instr->right());
2210 XMMRegister result = ToDoubleRegister(instr->result()); 2210 XMMRegister result = ToDoubleRegister(instr->result());
2211 // Modulo uses a fixed result register.
2212 ASSERT(instr->op() == Token::MOD || left.is(result));
2213 switch (instr->op()) { 2211 switch (instr->op()) {
2214 case Token::ADD: 2212 case Token::ADD:
2215 __ addsd(left, right); 2213 __ addsd(left, right);
2216 break; 2214 break;
2217 case Token::SUB: 2215 case Token::SUB:
2218 __ subsd(left, right); 2216 __ subsd(left, right);
2219 break; 2217 break;
2220 case Token::MUL: 2218 case Token::MUL:
2221 __ mulsd(left, right); 2219 __ mulsd(left, right);
2222 break; 2220 break;
2223 case Token::DIV: 2221 case Token::DIV:
2224 __ divsd(left, right); 2222 __ divsd(left, right);
2225 // Don't delete this mov. It may improve performance on some CPUs, 2223 // Don't delete this mov. It may improve performance on some CPUs,
2226 // when there is a mulsd depending on the result 2224 // when there is a mulsd depending on the result
2227 __ movaps(left, left); 2225 __ movaps(left, left);
2228 break; 2226 break;
2229 case Token::MOD: { 2227 case Token::MOD: {
2230 // Pass two doubles as arguments on the stack. 2228 // Pass two doubles as arguments on the stack.
2231 __ PrepareCallCFunction(4, eax); 2229 __ PrepareCallCFunction(4, eax);
2232 __ movdbl(Operand(esp, 0 * kDoubleSize), left); 2230 __ movdbl(Operand(esp, 0 * kDoubleSize), left);
2233 __ movdbl(Operand(esp, 1 * kDoubleSize), right); 2231 __ movdbl(Operand(esp, 1 * kDoubleSize), right);
2234 __ CallCFunction( 2232 __ CallCFunction(
2235 ExternalReference::double_fp_operation(Token::MOD, isolate()), 2233 ExternalReference::double_fp_operation(Token::MOD, isolate()),
2236 4); 2234 4);
2237 2235
2238 // Return value is in st(0) on ia32. 2236 // Return value is in st(0) on ia32.
2239 // Store it into the (fixed) result register. 2237 // Store it into the result register.
2240 __ sub(Operand(esp), Immediate(kDoubleSize)); 2238 __ sub(Operand(esp), Immediate(kDoubleSize));
2241 __ fstp_d(Operand(esp, 0)); 2239 __ fstp_d(Operand(esp, 0));
2242 __ movdbl(result, Operand(esp, 0)); 2240 __ movdbl(result, Operand(esp, 0));
2243 __ add(Operand(esp), Immediate(kDoubleSize)); 2241 __ add(Operand(esp), Immediate(kDoubleSize));
2244 break; 2242 break;
2245 } 2243 }
2246 default: 2244 default:
2247 UNREACHABLE(); 2245 UNREACHABLE();
2248 break; 2246 break;
2249 } 2247 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 } 2286 }
2289 } 2287 }
2290 2288
2291 2289
2292 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 2290 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2293 ASSERT(ToRegister(instr->context()).is(esi)); 2291 ASSERT(ToRegister(instr->context()).is(esi));
2294 ASSERT(ToRegister(instr->left()).is(edx)); 2292 ASSERT(ToRegister(instr->left()).is(edx));
2295 ASSERT(ToRegister(instr->right()).is(eax)); 2293 ASSERT(ToRegister(instr->right()).is(eax));
2296 ASSERT(ToRegister(instr->result()).is(eax)); 2294 ASSERT(ToRegister(instr->result()).is(eax));
2297 2295
2298 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 2296 BinaryOpStub stub(instr->op());
2299 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2297 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2300 __ nop(); // Signals no inlined code. 2298 __ nop(); // Signals no inlined code.
2301 } 2299 }
2302 2300
2303 2301
2304 int LCodeGen::GetNextEmittedBlock() const { 2302 int LCodeGen::GetNextEmittedBlock() const {
2305 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 2303 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
2306 if (!chunk_->GetLabel(i)->HasReplacement()) return i; 2304 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
2307 } 2305 }
2308 return -1; 2306 return -1;
(...skipping 2973 matching lines...) Expand 10 before | Expand all | Expand 10 after
5282 // Pop FPU stack before deoptimizing. 5280 // Pop FPU stack before deoptimizing.
5283 __ fstp(0); 5281 __ fstp(0);
5284 DeoptimizeIf(not_zero, env); 5282 DeoptimizeIf(not_zero, env);
5285 } 5283 }
5286 __ jmp(&done, Label::kNear); 5284 __ jmp(&done, Label::kNear);
5287 } else { 5285 } else {
5288 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 5286 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
5289 } 5287 }
5290 5288
5291 __ bind(&load_smi); 5289 __ bind(&load_smi);
5292 // Clobbering a temp is faster than re-tagging the 5290 __ SmiUntag(input_reg); // Untag smi before converting to float.
5293 // input register since we avoid dependencies. 5291 __ push(input_reg);
5294 __ mov(temp_reg, input_reg);
5295 __ SmiUntag(temp_reg); // Untag smi before converting to float.
5296 __ push(temp_reg);
5297 __ fild_s(Operand(esp, 0)); 5292 __ fild_s(Operand(esp, 0));
5298 __ add(esp, Immediate(kPointerSize)); 5293 __ pop(input_reg);
5294 __ SmiTag(input_reg); // Retag smi.
5299 __ bind(&done); 5295 __ bind(&done);
5300 X87CommitWrite(res_reg); 5296 X87CommitWrite(res_reg);
5301 } 5297 }
5302 5298
5303 5299
5304 void LCodeGen::EmitNumberUntagD(Register input_reg, 5300 void LCodeGen::EmitNumberUntagD(Register input_reg,
5305 Register temp_reg, 5301 Register temp_reg,
5306 XMMRegister result_reg, 5302 XMMRegister result_reg,
5307 bool can_convert_undefined_to_nan, 5303 bool can_convert_undefined_to_nan,
5308 bool deoptimize_on_minus_zero, 5304 bool deoptimize_on_minus_zero,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5344 __ j(not_zero, &done, Label::kNear); 5340 __ j(not_zero, &done, Label::kNear);
5345 __ movmskpd(temp_reg, result_reg); 5341 __ movmskpd(temp_reg, result_reg);
5346 __ test_b(temp_reg, 1); 5342 __ test_b(temp_reg, 1);
5347 DeoptimizeIf(not_zero, env); 5343 DeoptimizeIf(not_zero, env);
5348 } 5344 }
5349 __ jmp(&done, Label::kNear); 5345 __ jmp(&done, Label::kNear);
5350 } else { 5346 } else {
5351 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 5347 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
5352 } 5348 }
5353 5349
5350 // Smi to XMM conversion
5354 __ bind(&load_smi); 5351 __ bind(&load_smi);
5355 // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the 5352 // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the
5356 // input register since we avoid dependencies. 5353 // input register since we avoid dependencies.
5357 __ mov(temp_reg, input_reg); 5354 __ mov(temp_reg, input_reg);
5358 __ SmiUntag(temp_reg); // Untag smi before converting to float. 5355 __ SmiUntag(temp_reg); // Untag smi before converting to float.
5359 __ Cvtsi2sd(result_reg, Operand(temp_reg)); 5356 __ Cvtsi2sd(result_reg, Operand(temp_reg));
5360 __ bind(&done); 5357 __ bind(&done);
5361 } 5358 }
5362 5359
5363 5360
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
5410 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 5407 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5411 private: 5408 private:
5412 LTaggedToI* instr_; 5409 LTaggedToI* instr_;
5413 }; 5410 };
5414 5411
5415 LOperand* input = instr->value(); 5412 LOperand* input = instr->value();
5416 ASSERT(input->IsRegister()); 5413 ASSERT(input->IsRegister());
5417 Register input_reg = ToRegister(input); 5414 Register input_reg = ToRegister(input);
5418 ASSERT(input_reg.is(ToRegister(instr->result()))); 5415 ASSERT(input_reg.is(ToRegister(instr->result())));
5419 5416
5420 DeferredTaggedToI* deferred = 5417 if (instr->hydrogen()->value()->representation().IsSmi()) {
5421 new(zone()) DeferredTaggedToI(this, instr, x87_stack_); 5418 __ SmiUntag(input_reg);
5419 } else {
5420 DeferredTaggedToI* deferred =
5421 new(zone()) DeferredTaggedToI(this, instr, x87_stack_);
5422 5422
5423 __ JumpIfNotSmi(input_reg, deferred->entry()); 5423 __ JumpIfNotSmi(input_reg, deferred->entry());
5424 __ SmiUntag(input_reg); 5424 __ SmiUntag(input_reg);
5425 __ bind(deferred->exit()); 5425 __ bind(deferred->exit());
5426 }
5426 } 5427 }
5427 5428
5428 5429
5429 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 5430 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5430 LOperand* input = instr->value(); 5431 LOperand* input = instr->value();
5431 ASSERT(input->IsRegister()); 5432 ASSERT(input->IsRegister());
5432 LOperand* temp = instr->temp(); 5433 LOperand* temp = instr->temp();
5433 ASSERT(temp->IsRegister()); 5434 ASSERT(temp->IsRegister());
5434 LOperand* result = instr->result(); 5435 LOperand* result = instr->result();
5435 ASSERT(result->IsDoubleRegister()); 5436 ASSERT(result->IsDoubleRegister());
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
6357 FixedArray::kHeaderSize - kPointerSize)); 6358 FixedArray::kHeaderSize - kPointerSize));
6358 __ bind(&done); 6359 __ bind(&done);
6359 } 6360 }
6360 6361
6361 6362
6362 #undef __ 6363 #undef __
6363 6364
6364 } } // namespace v8::internal 6365 } } // namespace v8::internal
6365 6366
6366 #endif // V8_TARGET_ARCH_IA32 6367 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698