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

Side by Side Diff: src/compiler/ia32/code-generator-ia32.cc

Issue 1064833002: [ia32] Match -0 - x with sign bit flip. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-codes-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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/ia32/assembler-ia32.h" 10 #include "src/ia32/assembler-ia32.h"
11 #include "src/ia32/macro-assembler-ia32.h" 11 #include "src/ia32/macro-assembler-ia32.h"
12 #include "src/scopes.h" 12 #include "src/scopes.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 namespace compiler { 16 namespace compiler {
17 17
18 #define __ masm()-> 18 #define __ masm()->
19 19
20 20
21 #define kScratchDoubleReg xmm0
22
23
21 // Adds IA-32 specific methods for decoding operands. 24 // Adds IA-32 specific methods for decoding operands.
22 class IA32OperandConverter : public InstructionOperandConverter { 25 class IA32OperandConverter : public InstructionOperandConverter {
23 public: 26 public:
24 IA32OperandConverter(CodeGenerator* gen, Instruction* instr) 27 IA32OperandConverter(CodeGenerator* gen, Instruction* instr)
25 : InstructionOperandConverter(gen, instr) {} 28 : InstructionOperandConverter(gen, instr) {}
26 29
27 Operand InputOperand(size_t index, int extra = 0) { 30 Operand InputOperand(size_t index, int extra = 0) {
28 return ToOperand(instr_->InputAt(index), extra); 31 return ToOperand(instr_->InputAt(index), extra);
29 } 32 }
30 33
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 break; 470 break;
468 case kSSEFloat32Max: 471 case kSSEFloat32Max:
469 __ maxss(i.InputDoubleRegister(0), i.InputOperand(1)); 472 __ maxss(i.InputDoubleRegister(0), i.InputOperand(1));
470 break; 473 break;
471 case kSSEFloat32Min: 474 case kSSEFloat32Min:
472 __ minss(i.InputDoubleRegister(0), i.InputOperand(1)); 475 __ minss(i.InputDoubleRegister(0), i.InputOperand(1));
473 break; 476 break;
474 case kSSEFloat32Sqrt: 477 case kSSEFloat32Sqrt:
475 __ sqrtss(i.OutputDoubleRegister(), i.InputOperand(0)); 478 __ sqrtss(i.OutputDoubleRegister(), i.InputOperand(0));
476 break; 479 break;
480 case kSSEFloat32Neg: {
481 // TODO(bmeurer): Use 128-bit constants.
482 // TODO(turbofan): Add AVX version with relaxed register constraints.
483 __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
484 __ psllq(kScratchDoubleReg, 31);
485 __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg);
486 break;
487 }
477 case kSSEFloat64Cmp: 488 case kSSEFloat64Cmp:
478 __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); 489 __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
479 break; 490 break;
480 case kSSEFloat64Add: 491 case kSSEFloat64Add:
481 __ addsd(i.InputDoubleRegister(0), i.InputOperand(1)); 492 __ addsd(i.InputDoubleRegister(0), i.InputOperand(1));
482 break; 493 break;
483 case kSSEFloat64Sub: 494 case kSSEFloat64Sub:
484 __ subsd(i.InputDoubleRegister(0), i.InputOperand(1)); 495 __ subsd(i.InputDoubleRegister(0), i.InputOperand(1));
485 break; 496 break;
486 case kSSEFloat64Mul: 497 case kSSEFloat64Mul:
(...skipping 26 matching lines...) Expand all
513 __ fnstsw_ax(); 524 __ fnstsw_ax();
514 __ sahf(); 525 __ sahf();
515 __ j(parity_even, &mod_loop); 526 __ j(parity_even, &mod_loop);
516 // Move output to stack and clean up. 527 // Move output to stack and clean up.
517 __ fstp(1); 528 __ fstp(1);
518 __ fstp_d(Operand(esp, 0)); 529 __ fstp_d(Operand(esp, 0));
519 __ movsd(i.OutputDoubleRegister(), Operand(esp, 0)); 530 __ movsd(i.OutputDoubleRegister(), Operand(esp, 0));
520 __ add(esp, Immediate(kDoubleSize)); 531 __ add(esp, Immediate(kDoubleSize));
521 break; 532 break;
522 } 533 }
534 case kSSEFloat64Neg: {
535 // TODO(bmeurer): Use 128-bit constants.
536 // TODO(turbofan): Add AVX version with relaxed register constraints.
537 __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
538 __ psllq(kScratchDoubleReg, 63);
539 __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg);
540 break;
541 }
523 case kSSEFloat64Sqrt: 542 case kSSEFloat64Sqrt:
524 __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0)); 543 __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0));
525 break; 544 break;
526 case kSSEFloat64Round: { 545 case kSSEFloat64Round: {
527 CpuFeatureScope sse_scope(masm(), SSE4_1); 546 CpuFeatureScope sse_scope(masm(), SSE4_1);
528 RoundingMode const mode = 547 RoundingMode const mode =
529 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 548 static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
530 __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); 549 __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
531 break; 550 break;
532 } 551 }
533 case kSSEFloat32ToFloat64: 552 case kSSEFloat32ToFloat64:
534 __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0)); 553 __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0));
535 break; 554 break;
536 case kSSEFloat64ToFloat32: 555 case kSSEFloat64ToFloat32:
537 __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0)); 556 __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0));
538 break; 557 break;
539 case kSSEFloat64ToInt32: 558 case kSSEFloat64ToInt32:
540 __ cvttsd2si(i.OutputRegister(), i.InputOperand(0)); 559 __ cvttsd2si(i.OutputRegister(), i.InputOperand(0));
541 break; 560 break;
542 case kSSEFloat64ToUint32: { 561 case kSSEFloat64ToUint32: {
543 XMMRegister scratch = xmm0; 562 __ Move(kScratchDoubleReg, -2147483648.0);
544 __ Move(scratch, -2147483648.0); 563 __ addsd(kScratchDoubleReg, i.InputOperand(0));
545 __ addsd(scratch, i.InputOperand(0)); 564 __ cvttsd2si(i.OutputRegister(), kScratchDoubleReg);
546 __ cvttsd2si(i.OutputRegister(), scratch);
547 __ add(i.OutputRegister(), Immediate(0x80000000)); 565 __ add(i.OutputRegister(), Immediate(0x80000000));
548 break; 566 break;
549 } 567 }
550 case kSSEInt32ToFloat64: 568 case kSSEInt32ToFloat64:
551 __ cvtsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); 569 __ cvtsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
552 break; 570 break;
553 case kSSEUint32ToFloat64: 571 case kSSEUint32ToFloat64:
554 __ LoadUint32(i.OutputDoubleRegister(), i.InputOperand(0)); 572 __ LoadUint32(i.OutputDoubleRegister(), i.InputOperand(0));
555 break; 573 break;
556 case kSSEFloat64ExtractLowWord32: 574 case kSSEFloat64ExtractLowWord32:
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 Operand dst = g.ToOperand(destination); 1314 Operand dst = g.ToOperand(destination);
1297 __ movsd(dst, src); 1315 __ movsd(dst, src);
1298 } 1316 }
1299 } else if (source->IsDoubleStackSlot()) { 1317 } else if (source->IsDoubleStackSlot()) {
1300 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); 1318 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
1301 Operand src = g.ToOperand(source); 1319 Operand src = g.ToOperand(source);
1302 if (destination->IsDoubleRegister()) { 1320 if (destination->IsDoubleRegister()) {
1303 XMMRegister dst = g.ToDoubleRegister(destination); 1321 XMMRegister dst = g.ToDoubleRegister(destination);
1304 __ movsd(dst, src); 1322 __ movsd(dst, src);
1305 } else { 1323 } else {
1306 // We rely on having xmm0 available as a fixed scratch register.
1307 Operand dst = g.ToOperand(destination); 1324 Operand dst = g.ToOperand(destination);
1308 __ movsd(xmm0, src); 1325 __ movsd(kScratchDoubleReg, src);
1309 __ movsd(dst, xmm0); 1326 __ movsd(dst, kScratchDoubleReg);
1310 } 1327 }
1311 } else { 1328 } else {
1312 UNREACHABLE(); 1329 UNREACHABLE();
1313 } 1330 }
1314 } 1331 }
1315 1332
1316 1333
1317 void CodeGenerator::AssembleSwap(InstructionOperand* source, 1334 void CodeGenerator::AssembleSwap(InstructionOperand* source,
1318 InstructionOperand* destination) { 1335 InstructionOperand* destination) {
1319 IA32OperandConverter g(this, NULL); 1336 IA32OperandConverter g(this, NULL);
1320 // Dispatch on the source and destination operand kinds. Not all 1337 // Dispatch on the source and destination operand kinds. Not all
1321 // combinations are possible. 1338 // combinations are possible.
1322 if (source->IsRegister() && destination->IsRegister()) { 1339 if (source->IsRegister() && destination->IsRegister()) {
1323 // Register-register. 1340 // Register-register.
1324 Register src = g.ToRegister(source); 1341 Register src = g.ToRegister(source);
1325 Register dst = g.ToRegister(destination); 1342 Register dst = g.ToRegister(destination);
1326 __ xchg(dst, src); 1343 __ xchg(dst, src);
1327 } else if (source->IsRegister() && destination->IsStackSlot()) { 1344 } else if (source->IsRegister() && destination->IsStackSlot()) {
1328 // Register-memory. 1345 // Register-memory.
1329 __ xchg(g.ToRegister(source), g.ToOperand(destination)); 1346 __ xchg(g.ToRegister(source), g.ToOperand(destination));
1330 } else if (source->IsStackSlot() && destination->IsStackSlot()) { 1347 } else if (source->IsStackSlot() && destination->IsStackSlot()) {
1331 // Memory-memory. 1348 // Memory-memory.
1332 Operand src = g.ToOperand(source); 1349 Operand src = g.ToOperand(source);
1333 Operand dst = g.ToOperand(destination); 1350 Operand dst = g.ToOperand(destination);
1334 __ push(dst); 1351 __ push(dst);
1335 __ push(src); 1352 __ push(src);
1336 __ pop(dst); 1353 __ pop(dst);
1337 __ pop(src); 1354 __ pop(src);
1338 } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) { 1355 } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) {
1339 // XMM register-register swap. We rely on having xmm0 1356 // XMM register-register swap.
1340 // available as a fixed scratch register.
1341 XMMRegister src = g.ToDoubleRegister(source); 1357 XMMRegister src = g.ToDoubleRegister(source);
1342 XMMRegister dst = g.ToDoubleRegister(destination); 1358 XMMRegister dst = g.ToDoubleRegister(destination);
1343 __ movaps(xmm0, src); 1359 __ movaps(kScratchDoubleReg, src);
1344 __ movaps(src, dst); 1360 __ movaps(src, dst);
1345 __ movaps(dst, xmm0); 1361 __ movaps(dst, kScratchDoubleReg);
1346 } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) { 1362 } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
1347 // XMM register-memory swap. We rely on having xmm0 1363 // XMM register-memory swap.
1348 // available as a fixed scratch register.
1349 XMMRegister reg = g.ToDoubleRegister(source); 1364 XMMRegister reg = g.ToDoubleRegister(source);
1350 Operand other = g.ToOperand(destination); 1365 Operand other = g.ToOperand(destination);
1351 __ movsd(xmm0, other); 1366 __ movsd(kScratchDoubleReg, other);
1352 __ movsd(other, reg); 1367 __ movsd(other, reg);
1353 __ movaps(reg, xmm0); 1368 __ movaps(reg, kScratchDoubleReg);
1354 } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) { 1369 } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) {
1355 // Double-width memory-to-memory. 1370 // Double-width memory-to-memory.
1356 Operand src0 = g.ToOperand(source); 1371 Operand src0 = g.ToOperand(source);
1357 Operand src1 = g.HighOperand(source); 1372 Operand src1 = g.HighOperand(source);
1358 Operand dst0 = g.ToOperand(destination); 1373 Operand dst0 = g.ToOperand(destination);
1359 Operand dst1 = g.HighOperand(destination); 1374 Operand dst1 = g.HighOperand(destination);
1360 __ movsd(xmm0, dst0); // Save destination in xmm0. 1375 __ movsd(kScratchDoubleReg, dst0); // Save destination in scratch register.
1361 __ push(src0); // Then use stack to copy source to destination. 1376 __ push(src0); // Then use stack to copy source to destination.
1362 __ pop(dst0); 1377 __ pop(dst0);
1363 __ push(src1); 1378 __ push(src1);
1364 __ pop(dst1); 1379 __ pop(dst1);
1365 __ movsd(src0, xmm0); 1380 __ movsd(src0, kScratchDoubleReg);
1366 } else { 1381 } else {
1367 // No other combinations are possible. 1382 // No other combinations are possible.
1368 UNREACHABLE(); 1383 UNREACHABLE();
1369 } 1384 }
1370 } 1385 }
1371 1386
1372 1387
1373 void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) { 1388 void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
1374 for (size_t index = 0; index < target_count; ++index) { 1389 for (size_t index = 0; index < target_count; ++index) {
1375 __ dd(targets[index]); 1390 __ dd(targets[index]);
(...skipping 16 matching lines...) Expand all
1392 } 1407 }
1393 } 1408 }
1394 MarkLazyDeoptSite(); 1409 MarkLazyDeoptSite();
1395 } 1410 }
1396 1411
1397 #undef __ 1412 #undef __
1398 1413
1399 } // namespace compiler 1414 } // namespace compiler
1400 } // namespace internal 1415 } // namespace internal
1401 } // namespace v8 1416 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-codes-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698