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

Side by Side Diff: src/IceInstARM32.cpp

Issue 1694533002: Add move vector to the integrated ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Add test for vector moves. Created 4 years, 10 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
OLDNEW
1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 Type Ty = Dest->getType(); 1429 Type Ty = Dest->getType();
1430 const bool IsVector = isVectorType(Ty); 1430 const bool IsVector = isVectorType(Ty);
1431 const bool IsScalarFP = isScalarFloatingType(Ty); 1431 const bool IsScalarFP = isScalarFloatingType(Ty);
1432 const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0); 1432 const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0);
1433 const bool IsVMove = (IsVector || IsScalarFP || CoreVFPMove); 1433 const bool IsVMove = (IsVector || IsScalarFP || CoreVFPMove);
1434 const char *Opcode = IsVMove ? "vmov" : "mov"; 1434 const char *Opcode = IsVMove ? "vmov" : "mov";
1435 // when vmov{c}'ing, we need to emit a width string. Otherwise, the 1435 // when vmov{c}'ing, we need to emit a width string. Otherwise, the
1436 // assembler might be tempted to assume we want a vector vmov{c}, and that 1436 // assembler might be tempted to assume we want a vector vmov{c}, and that
1437 // is disallowed because ARM. 1437 // is disallowed because ARM.
1438 const char *WidthString = !CoreVFPMove ? getVecWidthString(Ty) : ""; 1438 const char *WidthString = !CoreVFPMove ? getVecWidthString(Ty) : "";
1439 CondARM32::Cond Cond = getPredicate();
Jim Stichnoth 2016/02/12 01:38:55 const
1440 if (IsVector)
John 2016/02/11 23:59:54 This is a serious error. Maybe llvm::report_fatal_
1441 assert(CondARM32::isUnconditional(Cond) &&
1442 "Moves on vectors must be unconditional!");
1439 Str << "\t" << Opcode; 1443 Str << "\t" << Opcode;
1440 if (IsVMove) { 1444 if (IsVMove) {
1441 Str << getPredicate() << WidthString; 1445 Str << Cond << WidthString;
1442 } else { 1446 } else {
1443 Str << WidthString << getPredicate(); 1447 Str << WidthString << Cond;
1444 } 1448 }
1445 Str << "\t"; 1449 Str << "\t";
1446 Dest->emit(Func); 1450 Dest->emit(Func);
1447 Str << ", "; 1451 Str << ", ";
1448 Src0->emit(Func); 1452 Src0->emit(Func);
1449 } 1453 }
1450 1454
1451 void InstARM32Mov::emit(const Cfg *Func) const { 1455 void InstARM32Mov::emit(const Cfg *Func) const {
1452 if (!BuildDefs::dump()) 1456 if (!BuildDefs::dump())
1453 return; 1457 return;
1454 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); 1458 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
1455 if (isMultiDest()) { 1459 if (isMultiDest()) {
1456 emitMultiDestSingleSource(Func); 1460 emitMultiDestSingleSource(Func);
1457 return; 1461 return;
1458 } 1462 }
1459 1463
1460 if (isMultiSource()) { 1464 if (isMultiSource()) {
1461 emitSingleDestMultiSource(Func); 1465 emitSingleDestMultiSource(Func);
1462 return; 1466 return;
1463 } 1467 }
1464 1468
1465 emitSingleDestSingleSource(Func); 1469 emitSingleDestSingleSource(Func);
1466 } 1470 }
1467 1471
1468 void InstARM32Mov::emitIAS(const Cfg *Func) const { 1472 void InstARM32Mov::emitIAS(const Cfg *Func) const {
1469 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 1473 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
1470 Variable *Dest = getDest(); 1474 const Variable *Dest = getDest();
1471 Operand *Src0 = getSrc(0); 1475 Operand *Src0 = getSrc(0);
1476 const CondARM32::Cond Cond = getPredicate();
1472 if (!Dest->hasReg()) { 1477 if (!Dest->hasReg()) {
1473 llvm::report_fatal_error("mov can't store."); 1478 llvm::report_fatal_error("mov can't store.");
1474 } 1479 }
1475 if (isMemoryAccess(Src0)) { 1480 if (isMemoryAccess(Src0)) {
1476 llvm::report_fatal_error("mov can't load."); 1481 llvm::report_fatal_error("mov can't load.");
1477 } 1482 }
1478 1483
1479 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); 1484 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
1480 if (isMultiDest()) { 1485 if (isMultiDest()) {
1481 Asm->vmovrrd(Dest, getDestHi(), Src0, getPredicate()); 1486 Asm->vmovrrd(Dest, getDestHi(), Src0, Cond);
1482 return; 1487 return;
1483 } 1488 }
1484 if (isMultiSource()) { 1489 if (isMultiSource()) {
1485 Asm->vmovdrr(Dest, Src0, getSrc(1), getPredicate()); 1490 Asm->vmovdrr(Dest, Src0, getSrc(1), Cond);
1486 return; 1491 return;
1487 } 1492 }
1488 1493
1489 const Type DestTy = Dest->getType(); 1494 const Type DestTy = Dest->getType();
1490 const Type SrcTy = Src0->getType(); 1495 const Type SrcTy = Src0->getType();
1491 switch (DestTy) { 1496 switch (DestTy) {
1492 default: 1497 default:
1493 break; // Error 1498 break; // Error
1494 case IceType_i1: 1499 case IceType_i1:
1495 case IceType_i8: 1500 case IceType_i8:
1496 case IceType_i16: 1501 case IceType_i16:
1497 case IceType_i32: 1502 case IceType_i32:
1498 switch (SrcTy) { 1503 switch (SrcTy) {
1499 default: 1504 default:
1500 break; // Error 1505 break; // Error
1501 case IceType_i1: 1506 case IceType_i1:
1502 case IceType_i8: 1507 case IceType_i8:
1503 case IceType_i16: 1508 case IceType_i16:
1504 case IceType_i32: 1509 case IceType_i32:
1505 case IceType_i64: 1510 case IceType_i64:
1506 Asm->mov(Dest, Src0, getPredicate()); 1511 Asm->mov(Dest, Src0, Cond);
1507 return; 1512 return;
1508 case IceType_f32: 1513 case IceType_f32:
1509 Asm->vmovrs(Dest, Src0, getPredicate()); 1514 Asm->vmovrs(Dest, Src0, Cond);
1510 return; 1515 return;
1511 } 1516 }
1512 break; // Error 1517 break; // Error
1513 case IceType_i64: 1518 case IceType_i64:
1514 if (isScalarIntegerType(SrcTy)) { 1519 if (isScalarIntegerType(SrcTy)) {
1515 Asm->mov(Dest, Src0, getPredicate()); 1520 Asm->mov(Dest, Src0, Cond);
1516 return; 1521 return;
1517 } 1522 }
1518 if (SrcTy == IceType_f64) { 1523 if (SrcTy == IceType_f64) {
1519 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) { 1524 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
1520 Asm->vmovdd(Dest, Var, getPredicate()); 1525 Asm->vmovdd(Dest, Var, Cond);
1521 return; 1526 return;
1522 } 1527 }
1523 if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) { 1528 if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
1524 Asm->vmovd(Dest, FpImm, getPredicate()); 1529 Asm->vmovd(Dest, FpImm, Cond);
1525 return; 1530 return;
1526 } 1531 }
1527 } 1532 }
1528 break; // Error 1533 break; // Error
1529 case IceType_f32: 1534 case IceType_f32:
1530 switch (SrcTy) { 1535 switch (SrcTy) {
1531 default: 1536 default:
1532 break; // Error 1537 break; // Error
1533 case IceType_i1: 1538 case IceType_i1:
1534 case IceType_i8: 1539 case IceType_i8:
1535 case IceType_i16: 1540 case IceType_i16:
1536 case IceType_i32: 1541 case IceType_i32:
1537 return Asm->vmovsr(Dest, Src0, getPredicate()); 1542 return Asm->vmovsr(Dest, Src0, Cond);
1538 case IceType_f32: 1543 case IceType_f32:
1539 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) { 1544 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
1540 Asm->vmovss(Dest, Var, getPredicate()); 1545 Asm->vmovss(Dest, Var, Cond);
1541 return; 1546 return;
1542 } 1547 }
1543 if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) { 1548 if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
1544 Asm->vmovs(Dest, FpImm, getPredicate()); 1549 Asm->vmovs(Dest, FpImm, Cond);
1545 return; 1550 return;
1546 } 1551 }
1547 break; // Error 1552 break; // Error
1548 } 1553 }
1549 break; // Error 1554 break; // Error
1550 case IceType_f64: 1555 case IceType_f64:
1551 if (SrcTy == IceType_f64) { 1556 if (SrcTy == IceType_f64) {
1552 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) { 1557 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
1553 Asm->vmovdd(Dest, Var, getPredicate()); 1558 Asm->vmovdd(Dest, Var, Cond);
1554 return; 1559 return;
1555 } 1560 }
1556 if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) { 1561 if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
1557 Asm->vmovd(Dest, FpImm, getPredicate()); 1562 Asm->vmovd(Dest, FpImm, Cond);
1558 return; 1563 return;
1559 } 1564 }
1560 } 1565 }
1561 break; // Error 1566 break; // Error
1562 case IceType_v4i1: 1567 case IceType_v4i1:
1563 case IceType_v8i1: 1568 case IceType_v8i1:
1564 case IceType_v16i1: 1569 case IceType_v16i1:
1565 case IceType_v16i8: 1570 case IceType_v16i8:
1566 case IceType_v8i16: 1571 case IceType_v8i16:
1567 case IceType_v4i32: 1572 case IceType_v4i32:
1568 case IceType_v4f32: 1573 case IceType_v4f32:
1569 // TODO(kschimpf): Add vector moves. 1574 assert(CondARM32::isUnconditional(Cond) &&
1570 emitUsingTextFixup(Func); 1575 "Moves on <4 x f32> must be unconditional!");
1576 assert(SrcTy == DestTy && "Mov on different vector types");
1577 Asm->vorrq(Dest, Src0, Src0);
1571 return; 1578 return;
1572 } 1579 }
1573 llvm::report_fatal_error("Mov: don't know how to move " + 1580 llvm::report_fatal_error("Mov: don't know how to move " +
1574 typeIceString(SrcTy) + " to " + 1581 typeIceString(SrcTy) + " to " +
1575 typeIceString(DestTy)); 1582 typeIceString(DestTy));
1576 } 1583 }
1577 1584
1578 void InstARM32Mov::dump(const Cfg *Func) const { 1585 void InstARM32Mov::dump(const Cfg *Func) const {
1579 if (!BuildDefs::dump()) 1586 if (!BuildDefs::dump())
1580 return; 1587 return;
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2769 2776
2770 template class InstARM32FourAddrGPR<InstARM32::Mla>; 2777 template class InstARM32FourAddrGPR<InstARM32::Mla>;
2771 template class InstARM32FourAddrGPR<InstARM32::Mls>; 2778 template class InstARM32FourAddrGPR<InstARM32::Mls>;
2772 2779
2773 template class InstARM32CmpLike<InstARM32::Cmn>; 2780 template class InstARM32CmpLike<InstARM32::Cmn>;
2774 template class InstARM32CmpLike<InstARM32::Cmp>; 2781 template class InstARM32CmpLike<InstARM32::Cmp>;
2775 template class InstARM32CmpLike<InstARM32::Tst>; 2782 template class InstARM32CmpLike<InstARM32::Tst>;
2776 2783
2777 } // end of namespace ARM32 2784 } // end of namespace ARM32
2778 } // end of namespace Ice 2785 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698