| OLD | NEW |
| 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// | 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// |
| 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 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 } | 429 } |
| 430 | 430 |
| 431 if (Label) { | 431 if (Label) { |
| 432 Str << "\t" << Label->getName(Func); | 432 Str << "\t" << Label->getName(Func); |
| 433 } else { | 433 } else { |
| 434 if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) { | 434 if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) { |
| 435 Str << "\t" << getTargetFalse()->getAsmName(); | 435 Str << "\t" << getTargetFalse()->getAsmName(); |
| 436 } else { | 436 } else { |
| 437 Str << "\t" << getTargetTrue()->getAsmName(); | 437 Str << "\t" << getTargetTrue()->getAsmName(); |
| 438 if (getTargetFalse()) { | 438 if (getTargetFalse()) { |
| 439 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); | 439 Str << "\n\t" |
| 440 "jmp\t" << getTargetFalse()->getAsmName(); |
| 440 } | 441 } |
| 441 } | 442 } |
| 442 } | 443 } |
| 443 } | 444 } |
| 444 | 445 |
| 445 template <class Machine> | 446 template <class Machine> |
| 446 void InstX86Br<Machine>::emitIAS(const Cfg *Func) const { | 447 void InstX86Br<Machine>::emitIAS(const Cfg *Func) const { |
| 447 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 448 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 448 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 449 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 449 if (Label) { | 450 if (Label) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 } | 497 } |
| 497 | 498 |
| 498 Str << " // (" << (isNear() ? "near" : "far") << " jump)"; | 499 Str << " // (" << (isNear() ? "near" : "far") << " jump)"; |
| 499 } | 500 } |
| 500 | 501 |
| 501 template <class Machine> void InstX86Jmp<Machine>::emit(const Cfg *Func) const { | 502 template <class Machine> void InstX86Jmp<Machine>::emit(const Cfg *Func) const { |
| 502 if (!BuildDefs::dump()) | 503 if (!BuildDefs::dump()) |
| 503 return; | 504 return; |
| 504 Ostream &Str = Func->getContext()->getStrEmit(); | 505 Ostream &Str = Func->getContext()->getStrEmit(); |
| 505 assert(this->getSrcSize() == 1); | 506 assert(this->getSrcSize() == 1); |
| 506 Str << "\tjmp\t*"; | 507 Str << "\t" |
| 508 "jmp\t*"; |
| 507 getJmpTarget()->emit(Func); | 509 getJmpTarget()->emit(Func); |
| 508 } | 510 } |
| 509 | 511 |
| 510 template <class Machine> | 512 template <class Machine> |
| 511 void InstX86Jmp<Machine>::emitIAS(const Cfg *Func) const { | 513 void InstX86Jmp<Machine>::emitIAS(const Cfg *Func) const { |
| 512 // Note: Adapted (mostly copied) from InstX86Call<Machine>::emitIAS(). | 514 // Note: Adapted (mostly copied) from InstX86Call<Machine>::emitIAS(). |
| 513 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 515 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 514 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 516 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 515 Operand *Target = getJmpTarget(); | 517 Operand *Target = getJmpTarget(); |
| 516 if (const auto *Var = llvm::dyn_cast<Variable>(Target)) { | 518 if (const auto *Var = llvm::dyn_cast<Variable>(Target)) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 Str << "jmp "; | 555 Str << "jmp "; |
| 554 getJmpTarget()->dump(Func); | 556 getJmpTarget()->dump(Func); |
| 555 } | 557 } |
| 556 | 558 |
| 557 template <class Machine> | 559 template <class Machine> |
| 558 void InstX86Call<Machine>::emit(const Cfg *Func) const { | 560 void InstX86Call<Machine>::emit(const Cfg *Func) const { |
| 559 if (!BuildDefs::dump()) | 561 if (!BuildDefs::dump()) |
| 560 return; | 562 return; |
| 561 Ostream &Str = Func->getContext()->getStrEmit(); | 563 Ostream &Str = Func->getContext()->getStrEmit(); |
| 562 assert(this->getSrcSize() == 1); | 564 assert(this->getSrcSize() == 1); |
| 563 Str << "\tcall\t"; | 565 Str << "\t" |
| 566 "call\t"; |
| 564 Operand *CallTarget = getCallTarget(); | 567 Operand *CallTarget = getCallTarget(); |
| 565 auto *Target = InstX86Base<Machine>::getTarget(Func); | 568 auto *Target = InstX86Base<Machine>::getTarget(Func); |
| 566 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(CallTarget)) { | 569 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(CallTarget)) { |
| 567 // Emit without a leading '$'. | 570 // Emit without a leading '$'. |
| 568 Str << CI->getValue(); | 571 Str << CI->getValue(); |
| 569 } else if (const auto DirectCallTarget = | 572 } else if (const auto DirectCallTarget = |
| 570 llvm::dyn_cast<ConstantRelocatable>(CallTarget)) { | 573 llvm::dyn_cast<ConstantRelocatable>(CallTarget)) { |
| 571 DirectCallTarget->emitWithoutPrefix(Target); | 574 DirectCallTarget->emitWithoutPrefix(Target); |
| 572 } else { | 575 } else { |
| 573 Str << "*"; | 576 Str << "*"; |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 } | 993 } |
| 991 | 994 |
| 992 template <class Machine> | 995 template <class Machine> |
| 993 void InstX86Sqrtss<Machine>::emit(const Cfg *Func) const { | 996 void InstX86Sqrtss<Machine>::emit(const Cfg *Func) const { |
| 994 if (!BuildDefs::dump()) | 997 if (!BuildDefs::dump()) |
| 995 return; | 998 return; |
| 996 Ostream &Str = Func->getContext()->getStrEmit(); | 999 Ostream &Str = Func->getContext()->getStrEmit(); |
| 997 assert(this->getSrcSize() == 1); | 1000 assert(this->getSrcSize() == 1); |
| 998 Type Ty = this->getSrc(0)->getType(); | 1001 Type Ty = this->getSrc(0)->getType(); |
| 999 assert(isScalarFloatingType(Ty)); | 1002 assert(isScalarFloatingType(Ty)); |
| 1000 Str << "\tsqrt" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString | 1003 Str << "\t" |
| 1004 "sqrt" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString |
| 1001 << "\t"; | 1005 << "\t"; |
| 1002 this->getSrc(0)->emit(Func); | 1006 this->getSrc(0)->emit(Func); |
| 1003 Str << ", "; | 1007 Str << ", "; |
| 1004 this->getDest()->emit(Func); | 1008 this->getDest()->emit(Func); |
| 1005 } | 1009 } |
| 1006 | 1010 |
| 1007 template <class Machine> | 1011 template <class Machine> |
| 1008 void InstX86Addss<Machine>::emit(const Cfg *Func) const { | 1012 void InstX86Addss<Machine>::emit(const Cfg *Func) const { |
| 1009 if (!BuildDefs::dump()) | 1013 if (!BuildDefs::dump()) |
| 1010 return; | 1014 return; |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1319 return; | 1323 return; |
| 1320 Ostream &Str = Func->getContext()->getStrEmit(); | 1324 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1321 assert(this->getSrcSize() == 2); | 1325 assert(this->getSrcSize() == 2); |
| 1322 Variable *Dest = this->getDest(); | 1326 Variable *Dest = this->getDest(); |
| 1323 if (isByteSizedArithType(Dest->getType())) { | 1327 if (isByteSizedArithType(Dest->getType())) { |
| 1324 // The 8-bit version of imul only allows the form "imul r/m8". | 1328 // The 8-bit version of imul only allows the form "imul r/m8". |
| 1325 const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0)); | 1329 const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0)); |
| 1326 (void)Src0Var; | 1330 (void)Src0Var; |
| 1327 assert(Src0Var->getRegNum() == | 1331 assert(Src0Var->getRegNum() == |
| 1328 InstX86Base<Machine>::Traits::RegisterSet::Reg_al); | 1332 InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
| 1329 Str << "\timulb\t"; | 1333 Str << "\t" |
| 1334 "imulb\t"; |
| 1330 this->getSrc(1)->emit(Func); | 1335 this->getSrc(1)->emit(Func); |
| 1331 } else if (llvm::isa<Constant>(this->getSrc(1))) { | 1336 } else if (llvm::isa<Constant>(this->getSrc(1))) { |
| 1332 Str << "\timul" << this->getWidthString(Dest->getType()) << "\t"; | 1337 Str << "\t" |
| 1338 "imul" << this->getWidthString(Dest->getType()) << "\t"; |
| 1333 this->getSrc(1)->emit(Func); | 1339 this->getSrc(1)->emit(Func); |
| 1334 Str << ", "; | 1340 Str << ", "; |
| 1335 this->getSrc(0)->emit(Func); | 1341 this->getSrc(0)->emit(Func); |
| 1336 Str << ", "; | 1342 Str << ", "; |
| 1337 Dest->emit(Func); | 1343 Dest->emit(Func); |
| 1338 } else { | 1344 } else { |
| 1339 this->emitTwoAddress("imul", this, Func); | 1345 this->emitTwoAddress("imul", this, Func); |
| 1340 } | 1346 } |
| 1341 } | 1347 } |
| 1342 | 1348 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1372 | 1378 |
| 1373 template <class Machine> | 1379 template <class Machine> |
| 1374 void InstX86ImulImm<Machine>::emit(const Cfg *Func) const { | 1380 void InstX86ImulImm<Machine>::emit(const Cfg *Func) const { |
| 1375 if (!BuildDefs::dump()) | 1381 if (!BuildDefs::dump()) |
| 1376 return; | 1382 return; |
| 1377 Ostream &Str = Func->getContext()->getStrEmit(); | 1383 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1378 assert(this->getSrcSize() == 2); | 1384 assert(this->getSrcSize() == 2); |
| 1379 Variable *Dest = this->getDest(); | 1385 Variable *Dest = this->getDest(); |
| 1380 assert(Dest->getType() == IceType_i16 || Dest->getType() == IceType_i32); | 1386 assert(Dest->getType() == IceType_i16 || Dest->getType() == IceType_i32); |
| 1381 assert(llvm::isa<Constant>(this->getSrc(1))); | 1387 assert(llvm::isa<Constant>(this->getSrc(1))); |
| 1382 Str << "\timul" << this->getWidthString(Dest->getType()) << "\t"; | 1388 Str << "\t" |
| 1389 "imul" << this->getWidthString(Dest->getType()) << "\t"; |
| 1383 this->getSrc(1)->emit(Func); | 1390 this->getSrc(1)->emit(Func); |
| 1384 Str << ", "; | 1391 Str << ", "; |
| 1385 this->getSrc(0)->emit(Func); | 1392 this->getSrc(0)->emit(Func); |
| 1386 Str << ", "; | 1393 Str << ", "; |
| 1387 Dest->emit(Func); | 1394 Dest->emit(Func); |
| 1388 } | 1395 } |
| 1389 | 1396 |
| 1390 template <class Machine> | 1397 template <class Machine> |
| 1391 void InstX86ImulImm<Machine>::emitIAS(const Cfg *Func) const { | 1398 void InstX86ImulImm<Machine>::emitIAS(const Cfg *Func) const { |
| 1392 assert(this->getSrcSize() == 2); | 1399 assert(this->getSrcSize() == 2); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1442 (void)SrcReg; | 1449 (void)SrcReg; |
| 1443 switch (Src0->getType()) { | 1450 switch (Src0->getType()) { |
| 1444 default: | 1451 default: |
| 1445 llvm_unreachable("unexpected source type!"); | 1452 llvm_unreachable("unexpected source type!"); |
| 1446 break; | 1453 break; |
| 1447 case IceType_i8: | 1454 case IceType_i8: |
| 1448 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_al); | 1455 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
| 1449 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax || | 1456 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax || |
| 1450 DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ah); | 1457 DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ah); |
| 1451 Str << "\t" | 1458 Str << "\t" |
| 1452 << "cbtw"; | 1459 "cbtw"; |
| 1453 break; | 1460 break; |
| 1454 case IceType_i16: | 1461 case IceType_i16: |
| 1455 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); | 1462 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
| 1456 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); | 1463 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); |
| 1457 Str << "\t" | 1464 Str << "\t" |
| 1458 << "cwtd"; | 1465 "cwtd"; |
| 1459 break; | 1466 break; |
| 1460 case IceType_i32: | 1467 case IceType_i32: |
| 1461 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1468 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 1462 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1469 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1463 Str << "\t" | 1470 Str << "\t" |
| 1464 << "cltd"; | 1471 "cltd"; |
| 1465 break; | 1472 break; |
| 1466 case IceType_i64: | 1473 case IceType_i64: |
| 1467 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1474 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1468 Str << "\t" | 1475 Str << "\t" |
| 1469 << "cdto"; | 1476 "cdto"; |
| 1470 break; | 1477 break; |
| 1471 } | 1478 } |
| 1472 } | 1479 } |
| 1473 | 1480 |
| 1474 template <class Machine> | 1481 template <class Machine> |
| 1475 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { | 1482 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { |
| 1476 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1483 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1477 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1484 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1478 assert(this->getSrcSize() == 1); | 1485 assert(this->getSrcSize() == 1); |
| 1479 Operand *Src0 = this->getSrc(0); | 1486 Operand *Src0 = this->getSrc(0); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 if (!BuildDefs::dump()) | 1519 if (!BuildDefs::dump()) |
| 1513 return; | 1520 return; |
| 1514 Ostream &Str = Func->getContext()->getStrEmit(); | 1521 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1515 assert(this->getSrcSize() == 2); | 1522 assert(this->getSrcSize() == 2); |
| 1516 assert(llvm::isa<Variable>(this->getSrc(0))); | 1523 assert(llvm::isa<Variable>(this->getSrc(0))); |
| 1517 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == | 1524 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == |
| 1518 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1525 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 1519 assert( | 1526 assert( |
| 1520 this->getDest()->getRegNum() == | 1527 this->getDest()->getRegNum() == |
| 1521 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx? | 1528 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx? |
| 1522 Str << "\tmul" << this->getWidthString(this->getDest()->getType()) << "\t"; | 1529 Str << "\t" |
| 1530 "mul" << this->getWidthString(this->getDest()->getType()) << "\t"; |
| 1523 this->getSrc(1)->emit(Func); | 1531 this->getSrc(1)->emit(Func); |
| 1524 } | 1532 } |
| 1525 | 1533 |
| 1526 template <class Machine> | 1534 template <class Machine> |
| 1527 void InstX86Mul<Machine>::emitIAS(const Cfg *Func) const { | 1535 void InstX86Mul<Machine>::emitIAS(const Cfg *Func) const { |
| 1528 assert(this->getSrcSize() == 2); | 1536 assert(this->getSrcSize() == 2); |
| 1529 assert(llvm::isa<Variable>(this->getSrc(0))); | 1537 assert(llvm::isa<Variable>(this->getSrc(0))); |
| 1530 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == | 1538 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == |
| 1531 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1539 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 1532 assert( | 1540 assert( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1550 } | 1558 } |
| 1551 | 1559 |
| 1552 template <class Machine> | 1560 template <class Machine> |
| 1553 void InstX86Shld<Machine>::emit(const Cfg *Func) const { | 1561 void InstX86Shld<Machine>::emit(const Cfg *Func) const { |
| 1554 if (!BuildDefs::dump()) | 1562 if (!BuildDefs::dump()) |
| 1555 return; | 1563 return; |
| 1556 Ostream &Str = Func->getContext()->getStrEmit(); | 1564 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1557 Variable *Dest = this->getDest(); | 1565 Variable *Dest = this->getDest(); |
| 1558 assert(this->getSrcSize() == 3); | 1566 assert(this->getSrcSize() == 3); |
| 1559 assert(Dest == this->getSrc(0)); | 1567 assert(Dest == this->getSrc(0)); |
| 1560 Str << "\tshld" << this->getWidthString(Dest->getType()) << "\t"; | 1568 Str << "\t" |
| 1569 "shld" << this->getWidthString(Dest->getType()) << "\t"; |
| 1561 this->getSrc(2)->emit(Func); | 1570 this->getSrc(2)->emit(Func); |
| 1562 Str << ", "; | 1571 Str << ", "; |
| 1563 this->getSrc(1)->emit(Func); | 1572 this->getSrc(1)->emit(Func); |
| 1564 Str << ", "; | 1573 Str << ", "; |
| 1565 Dest->emit(Func); | 1574 Dest->emit(Func); |
| 1566 } | 1575 } |
| 1567 | 1576 |
| 1568 template <class Machine> | 1577 template <class Machine> |
| 1569 void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const { | 1578 void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const { |
| 1570 assert(this->getSrcSize() == 3); | 1579 assert(this->getSrcSize() == 3); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1590 } | 1599 } |
| 1591 | 1600 |
| 1592 template <class Machine> | 1601 template <class Machine> |
| 1593 void InstX86Shrd<Machine>::emit(const Cfg *Func) const { | 1602 void InstX86Shrd<Machine>::emit(const Cfg *Func) const { |
| 1594 if (!BuildDefs::dump()) | 1603 if (!BuildDefs::dump()) |
| 1595 return; | 1604 return; |
| 1596 Ostream &Str = Func->getContext()->getStrEmit(); | 1605 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1597 Variable *Dest = this->getDest(); | 1606 Variable *Dest = this->getDest(); |
| 1598 assert(this->getSrcSize() == 3); | 1607 assert(this->getSrcSize() == 3); |
| 1599 assert(Dest == this->getSrc(0)); | 1608 assert(Dest == this->getSrc(0)); |
| 1600 Str << "\tshrd" << this->getWidthString(Dest->getType()) << "\t"; | 1609 Str << "\t" |
| 1610 "shrd" << this->getWidthString(Dest->getType()) << "\t"; |
| 1601 this->getSrc(2)->emit(Func); | 1611 this->getSrc(2)->emit(Func); |
| 1602 Str << ", "; | 1612 Str << ", "; |
| 1603 this->getSrc(1)->emit(Func); | 1613 this->getSrc(1)->emit(Func); |
| 1604 Str << ", "; | 1614 Str << ", "; |
| 1605 Dest->emit(Func); | 1615 Dest->emit(Func); |
| 1606 } | 1616 } |
| 1607 | 1617 |
| 1608 template <class Machine> | 1618 template <class Machine> |
| 1609 void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const { | 1619 void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const { |
| 1610 assert(this->getSrcSize() == 3); | 1620 assert(this->getSrcSize() == 3); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1696 } | 1706 } |
| 1697 | 1707 |
| 1698 template <class Machine> | 1708 template <class Machine> |
| 1699 void InstX86Cmpps<Machine>::emit(const Cfg *Func) const { | 1709 void InstX86Cmpps<Machine>::emit(const Cfg *Func) const { |
| 1700 if (!BuildDefs::dump()) | 1710 if (!BuildDefs::dump()) |
| 1701 return; | 1711 return; |
| 1702 Ostream &Str = Func->getContext()->getStrEmit(); | 1712 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1703 assert(this->getSrcSize() == 2); | 1713 assert(this->getSrcSize() == 2); |
| 1704 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); | 1714 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); |
| 1705 Type DestTy = this->Dest->getType(); | 1715 Type DestTy = this->Dest->getType(); |
| 1706 Str << "\t"; | 1716 Str << "\t" |
| 1707 Str << "cmp" | 1717 "cmp" |
| 1708 << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString | 1718 << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString |
| 1709 << InstX86Base<Machine>::Traits::TypeAttributes[DestTy].PdPsString | 1719 << InstX86Base<Machine>::Traits::TypeAttributes[DestTy].PdPsString |
| 1710 << "\t"; | 1720 << "\t"; |
| 1711 this->getSrc(1)->emit(Func); | 1721 this->getSrc(1)->emit(Func); |
| 1712 Str << ", "; | 1722 Str << ", "; |
| 1713 this->getDest()->emit(Func); | 1723 this->getDest()->emit(Func); |
| 1714 } | 1724 } |
| 1715 | 1725 |
| 1716 template <class Machine> | 1726 template <class Machine> |
| 1717 void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const { | 1727 void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1743 template <class Machine> | 1753 template <class Machine> |
| 1744 void InstX86Cmpps<Machine>::dump(const Cfg *Func) const { | 1754 void InstX86Cmpps<Machine>::dump(const Cfg *Func) const { |
| 1745 if (!BuildDefs::dump()) | 1755 if (!BuildDefs::dump()) |
| 1746 return; | 1756 return; |
| 1747 Ostream &Str = Func->getContext()->getStrDump(); | 1757 Ostream &Str = Func->getContext()->getStrDump(); |
| 1748 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); | 1758 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); |
| 1749 this->dumpDest(Func); | 1759 this->dumpDest(Func); |
| 1750 Str << " = cmp" | 1760 Str << " = cmp" |
| 1751 << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString | 1761 << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString |
| 1752 << "ps" | 1762 << "ps" |
| 1753 << "\t"; | 1763 "\t"; |
| 1754 this->dumpSources(Func); | 1764 this->dumpSources(Func); |
| 1755 } | 1765 } |
| 1756 | 1766 |
| 1757 template <class Machine> | 1767 template <class Machine> |
| 1758 void InstX86Cmpxchg<Machine>::emit(const Cfg *Func) const { | 1768 void InstX86Cmpxchg<Machine>::emit(const Cfg *Func) const { |
| 1759 if (!BuildDefs::dump()) | 1769 if (!BuildDefs::dump()) |
| 1760 return; | 1770 return; |
| 1761 Ostream &Str = Func->getContext()->getStrEmit(); | 1771 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1762 assert(this->getSrcSize() == 3); | 1772 assert(this->getSrcSize() == 3); |
| 1763 if (this->Locked) { | 1773 if (this->Locked) { |
| 1764 Str << "\tlock"; | 1774 Str << "\t" |
| 1775 "lock"; |
| 1765 } | 1776 } |
| 1766 Str << "\tcmpxchg" << this->getWidthString(this->getSrc(0)->getType()) | 1777 Str << "\t" |
| 1767 << "\t"; | 1778 "cmpxchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 1768 this->getSrc(2)->emit(Func); | 1779 this->getSrc(2)->emit(Func); |
| 1769 Str << ", "; | 1780 Str << ", "; |
| 1770 this->getSrc(0)->emit(Func); | 1781 this->getSrc(0)->emit(Func); |
| 1771 } | 1782 } |
| 1772 | 1783 |
| 1773 template <class Machine> | 1784 template <class Machine> |
| 1774 void InstX86Cmpxchg<Machine>::emitIAS(const Cfg *Func) const { | 1785 void InstX86Cmpxchg<Machine>::emitIAS(const Cfg *Func) const { |
| 1775 assert(this->getSrcSize() == 3); | 1786 assert(this->getSrcSize() == 3); |
| 1776 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1787 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1777 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1788 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1803 this->dumpSources(Func); | 1814 this->dumpSources(Func); |
| 1804 } | 1815 } |
| 1805 | 1816 |
| 1806 template <class Machine> | 1817 template <class Machine> |
| 1807 void InstX86Cmpxchg8b<Machine>::emit(const Cfg *Func) const { | 1818 void InstX86Cmpxchg8b<Machine>::emit(const Cfg *Func) const { |
| 1808 if (!BuildDefs::dump()) | 1819 if (!BuildDefs::dump()) |
| 1809 return; | 1820 return; |
| 1810 Ostream &Str = Func->getContext()->getStrEmit(); | 1821 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1811 assert(this->getSrcSize() == 5); | 1822 assert(this->getSrcSize() == 5); |
| 1812 if (this->Locked) { | 1823 if (this->Locked) { |
| 1813 Str << "\tlock"; | 1824 Str << "\t" |
| 1825 "lock"; |
| 1814 } | 1826 } |
| 1815 Str << "\tcmpxchg8b\t"; | 1827 Str << "\t" |
| 1828 "cmpxchg8b\t"; |
| 1816 this->getSrc(0)->emit(Func); | 1829 this->getSrc(0)->emit(Func); |
| 1817 } | 1830 } |
| 1818 | 1831 |
| 1819 template <class Machine> | 1832 template <class Machine> |
| 1820 void InstX86Cmpxchg8b<Machine>::emitIAS(const Cfg *Func) const { | 1833 void InstX86Cmpxchg8b<Machine>::emitIAS(const Cfg *Func) const { |
| 1821 assert(this->getSrcSize() == 5); | 1834 assert(this->getSrcSize() == 5); |
| 1822 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1835 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1823 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1836 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1824 const auto Mem = | 1837 const auto Mem = |
| 1825 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( | 1838 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1842 } | 1855 } |
| 1843 Str << "cmpxchg8b "; | 1856 Str << "cmpxchg8b "; |
| 1844 this->dumpSources(Func); | 1857 this->dumpSources(Func); |
| 1845 } | 1858 } |
| 1846 | 1859 |
| 1847 template <class Machine> void InstX86Cvt<Machine>::emit(const Cfg *Func) const { | 1860 template <class Machine> void InstX86Cvt<Machine>::emit(const Cfg *Func) const { |
| 1848 if (!BuildDefs::dump()) | 1861 if (!BuildDefs::dump()) |
| 1849 return; | 1862 return; |
| 1850 Ostream &Str = Func->getContext()->getStrEmit(); | 1863 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1851 assert(this->getSrcSize() == 1); | 1864 assert(this->getSrcSize() == 1); |
| 1852 Str << "\tcvt"; | 1865 Str << "\t" |
| 1866 "cvt"; |
| 1853 if (isTruncating()) | 1867 if (isTruncating()) |
| 1854 Str << "t"; | 1868 Str << "t"; |
| 1855 Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) | 1869 Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) |
| 1856 ->getType()] | 1870 ->getType()] |
| 1857 .CvtString << "2" | 1871 .CvtString << "2" |
| 1858 << InstX86Base< | 1872 << InstX86Base< |
| 1859 Machine>::Traits::TypeAttributes[this->getDest()->getType()] | 1873 Machine>::Traits::TypeAttributes[this->getDest()->getType()] |
| 1860 .CvtString << "\t"; | 1874 .CvtString << "\t"; |
| 1861 this->getSrc(0)->emit(Func); | 1875 this->getSrc(0)->emit(Func); |
| 1862 Str << ", "; | 1876 Str << ", "; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1967 .CvtString << " "; | 1981 .CvtString << " "; |
| 1968 this->dumpSources(Func); | 1982 this->dumpSources(Func); |
| 1969 } | 1983 } |
| 1970 | 1984 |
| 1971 template <class Machine> | 1985 template <class Machine> |
| 1972 void InstX86Icmp<Machine>::emit(const Cfg *Func) const { | 1986 void InstX86Icmp<Machine>::emit(const Cfg *Func) const { |
| 1973 if (!BuildDefs::dump()) | 1987 if (!BuildDefs::dump()) |
| 1974 return; | 1988 return; |
| 1975 Ostream &Str = Func->getContext()->getStrEmit(); | 1989 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1976 assert(this->getSrcSize() == 2); | 1990 assert(this->getSrcSize() == 2); |
| 1977 Str << "\tcmp" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; | 1991 Str << "\t" |
| 1992 "cmp" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 1978 this->getSrc(1)->emit(Func); | 1993 this->getSrc(1)->emit(Func); |
| 1979 Str << ", "; | 1994 Str << ", "; |
| 1980 this->getSrc(0)->emit(Func); | 1995 this->getSrc(0)->emit(Func); |
| 1981 } | 1996 } |
| 1982 | 1997 |
| 1983 template <class Machine> | 1998 template <class Machine> |
| 1984 void InstX86Icmp<Machine>::emitIAS(const Cfg *Func) const { | 1999 void InstX86Icmp<Machine>::emitIAS(const Cfg *Func) const { |
| 1985 assert(this->getSrcSize() == 2); | 2000 assert(this->getSrcSize() == 2); |
| 1986 const Operand *Src0 = this->getSrc(0); | 2001 const Operand *Src0 = this->getSrc(0); |
| 1987 const Operand *Src1 = this->getSrc(1); | 2002 const Operand *Src1 = this->getSrc(1); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2011 Str << "cmp." << this->getSrc(0)->getType() << " "; | 2026 Str << "cmp." << this->getSrc(0)->getType() << " "; |
| 2012 this->dumpSources(Func); | 2027 this->dumpSources(Func); |
| 2013 } | 2028 } |
| 2014 | 2029 |
| 2015 template <class Machine> | 2030 template <class Machine> |
| 2016 void InstX86Ucomiss<Machine>::emit(const Cfg *Func) const { | 2031 void InstX86Ucomiss<Machine>::emit(const Cfg *Func) const { |
| 2017 if (!BuildDefs::dump()) | 2032 if (!BuildDefs::dump()) |
| 2018 return; | 2033 return; |
| 2019 Ostream &Str = Func->getContext()->getStrEmit(); | 2034 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2020 assert(this->getSrcSize() == 2); | 2035 assert(this->getSrcSize() == 2); |
| 2021 Str << "\tucomi" | 2036 Str << "\t" |
| 2037 "ucomi" |
| 2022 << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) | 2038 << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) |
| 2023 ->getType()] | 2039 ->getType()] |
| 2024 .SdSsString << "\t"; | 2040 .SdSsString << "\t"; |
| 2025 this->getSrc(1)->emit(Func); | 2041 this->getSrc(1)->emit(Func); |
| 2026 Str << ", "; | 2042 Str << ", "; |
| 2027 this->getSrc(0)->emit(Func); | 2043 this->getSrc(0)->emit(Func); |
| 2028 } | 2044 } |
| 2029 | 2045 |
| 2030 template <class Machine> | 2046 template <class Machine> |
| 2031 void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const { | 2047 void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2048 Ostream &Str = Func->getContext()->getStrDump(); | 2064 Ostream &Str = Func->getContext()->getStrDump(); |
| 2049 Str << "ucomiss." << this->getSrc(0)->getType() << " "; | 2065 Str << "ucomiss." << this->getSrc(0)->getType() << " "; |
| 2050 this->dumpSources(Func); | 2066 this->dumpSources(Func); |
| 2051 } | 2067 } |
| 2052 | 2068 |
| 2053 template <class Machine> void InstX86UD2<Machine>::emit(const Cfg *Func) const { | 2069 template <class Machine> void InstX86UD2<Machine>::emit(const Cfg *Func) const { |
| 2054 if (!BuildDefs::dump()) | 2070 if (!BuildDefs::dump()) |
| 2055 return; | 2071 return; |
| 2056 Ostream &Str = Func->getContext()->getStrEmit(); | 2072 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2057 assert(this->getSrcSize() == 0); | 2073 assert(this->getSrcSize() == 0); |
| 2058 Str << "\tud2"; | 2074 Str << "\t" |
| 2075 "ud2"; |
| 2059 } | 2076 } |
| 2060 | 2077 |
| 2061 template <class Machine> | 2078 template <class Machine> |
| 2062 void InstX86UD2<Machine>::emitIAS(const Cfg *Func) const { | 2079 void InstX86UD2<Machine>::emitIAS(const Cfg *Func) const { |
| 2063 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2080 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2064 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2081 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2065 Asm->ud2(); | 2082 Asm->ud2(); |
| 2066 } | 2083 } |
| 2067 | 2084 |
| 2068 template <class Machine> void InstX86UD2<Machine>::dump(const Cfg *Func) const { | 2085 template <class Machine> void InstX86UD2<Machine>::dump(const Cfg *Func) const { |
| 2069 if (!BuildDefs::dump()) | 2086 if (!BuildDefs::dump()) |
| 2070 return; | 2087 return; |
| 2071 Ostream &Str = Func->getContext()->getStrDump(); | 2088 Ostream &Str = Func->getContext()->getStrDump(); |
| 2072 Str << "ud2"; | 2089 Str << "ud2"; |
| 2073 } | 2090 } |
| 2074 | 2091 |
| 2075 template <class Machine> | 2092 template <class Machine> |
| 2076 void InstX86Test<Machine>::emit(const Cfg *Func) const { | 2093 void InstX86Test<Machine>::emit(const Cfg *Func) const { |
| 2077 if (!BuildDefs::dump()) | 2094 if (!BuildDefs::dump()) |
| 2078 return; | 2095 return; |
| 2079 Ostream &Str = Func->getContext()->getStrEmit(); | 2096 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2080 assert(this->getSrcSize() == 2); | 2097 assert(this->getSrcSize() == 2); |
| 2081 Str << "\ttest" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; | 2098 Str << "\t" |
| 2099 "test" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 2082 this->getSrc(1)->emit(Func); | 2100 this->getSrc(1)->emit(Func); |
| 2083 Str << ", "; | 2101 Str << ", "; |
| 2084 this->getSrc(0)->emit(Func); | 2102 this->getSrc(0)->emit(Func); |
| 2085 } | 2103 } |
| 2086 | 2104 |
| 2087 template <class Machine> | 2105 template <class Machine> |
| 2088 void InstX86Test<Machine>::emitIAS(const Cfg *Func) const { | 2106 void InstX86Test<Machine>::emitIAS(const Cfg *Func) const { |
| 2089 assert(this->getSrcSize() == 2); | 2107 assert(this->getSrcSize() == 2); |
| 2090 const Operand *Src0 = this->getSrc(0); | 2108 const Operand *Src0 = this->getSrc(0); |
| 2091 const Operand *Src1 = this->getSrc(1); | 2109 const Operand *Src1 = this->getSrc(1); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2115 Str << "test." << this->getSrc(0)->getType() << " "; | 2133 Str << "test." << this->getSrc(0)->getType() << " "; |
| 2116 this->dumpSources(Func); | 2134 this->dumpSources(Func); |
| 2117 } | 2135 } |
| 2118 | 2136 |
| 2119 template <class Machine> | 2137 template <class Machine> |
| 2120 void InstX86Mfence<Machine>::emit(const Cfg *Func) const { | 2138 void InstX86Mfence<Machine>::emit(const Cfg *Func) const { |
| 2121 if (!BuildDefs::dump()) | 2139 if (!BuildDefs::dump()) |
| 2122 return; | 2140 return; |
| 2123 Ostream &Str = Func->getContext()->getStrEmit(); | 2141 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2124 assert(this->getSrcSize() == 0); | 2142 assert(this->getSrcSize() == 0); |
| 2125 Str << "\tmfence"; | 2143 Str << "\t" |
| 2144 "mfence"; |
| 2126 } | 2145 } |
| 2127 | 2146 |
| 2128 template <class Machine> | 2147 template <class Machine> |
| 2129 void InstX86Mfence<Machine>::emitIAS(const Cfg *Func) const { | 2148 void InstX86Mfence<Machine>::emitIAS(const Cfg *Func) const { |
| 2130 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2149 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2131 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2150 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2132 Asm->mfence(); | 2151 Asm->mfence(); |
| 2133 } | 2152 } |
| 2134 | 2153 |
| 2135 template <class Machine> | 2154 template <class Machine> |
| 2136 void InstX86Mfence<Machine>::dump(const Cfg *Func) const { | 2155 void InstX86Mfence<Machine>::dump(const Cfg *Func) const { |
| 2137 if (!BuildDefs::dump()) | 2156 if (!BuildDefs::dump()) |
| 2138 return; | 2157 return; |
| 2139 Ostream &Str = Func->getContext()->getStrDump(); | 2158 Ostream &Str = Func->getContext()->getStrDump(); |
| 2140 Str << "mfence"; | 2159 Str << "mfence"; |
| 2141 } | 2160 } |
| 2142 | 2161 |
| 2143 template <class Machine> | 2162 template <class Machine> |
| 2144 void InstX86Store<Machine>::emit(const Cfg *Func) const { | 2163 void InstX86Store<Machine>::emit(const Cfg *Func) const { |
| 2145 if (!BuildDefs::dump()) | 2164 if (!BuildDefs::dump()) |
| 2146 return; | 2165 return; |
| 2147 Ostream &Str = Func->getContext()->getStrEmit(); | 2166 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2148 assert(this->getSrcSize() == 2); | 2167 assert(this->getSrcSize() == 2); |
| 2149 Type Ty = this->getSrc(0)->getType(); | 2168 Type Ty = this->getSrc(0)->getType(); |
| 2150 Str << "\tmov" << this->getWidthString(Ty) | 2169 Str << "\t" |
| 2170 "mov" << this->getWidthString(Ty) |
| 2151 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; | 2171 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; |
| 2152 this->getSrc(0)->emit(Func); | 2172 this->getSrc(0)->emit(Func); |
| 2153 Str << ", "; | 2173 Str << ", "; |
| 2154 this->getSrc(1)->emit(Func); | 2174 this->getSrc(1)->emit(Func); |
| 2155 } | 2175 } |
| 2156 | 2176 |
| 2157 template <class Machine> | 2177 template <class Machine> |
| 2158 void InstX86Store<Machine>::emitIAS(const Cfg *Func) const { | 2178 void InstX86Store<Machine>::emitIAS(const Cfg *Func) const { |
| 2159 assert(this->getSrcSize() == 2); | 2179 assert(this->getSrcSize() == 2); |
| 2160 const Operand *Dest = this->getSrc(1); | 2180 const Operand *Dest = this->getSrc(1); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2204 this->getSrc(0)->dump(Func); | 2224 this->getSrc(0)->dump(Func); |
| 2205 } | 2225 } |
| 2206 | 2226 |
| 2207 template <class Machine> | 2227 template <class Machine> |
| 2208 void InstX86StoreP<Machine>::emit(const Cfg *Func) const { | 2228 void InstX86StoreP<Machine>::emit(const Cfg *Func) const { |
| 2209 if (!BuildDefs::dump()) | 2229 if (!BuildDefs::dump()) |
| 2210 return; | 2230 return; |
| 2211 Ostream &Str = Func->getContext()->getStrEmit(); | 2231 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2212 assert(this->getSrcSize() == 2); | 2232 assert(this->getSrcSize() == 2); |
| 2213 assert(isVectorType(this->getSrc(1)->getType())); | 2233 assert(isVectorType(this->getSrc(1)->getType())); |
| 2214 Str << "\tmovups\t"; | 2234 Str << "\t" |
| 2235 "movups\t"; |
| 2215 this->getSrc(0)->emit(Func); | 2236 this->getSrc(0)->emit(Func); |
| 2216 Str << ", "; | 2237 Str << ", "; |
| 2217 this->getSrc(1)->emit(Func); | 2238 this->getSrc(1)->emit(Func); |
| 2218 } | 2239 } |
| 2219 | 2240 |
| 2220 template <class Machine> | 2241 template <class Machine> |
| 2221 void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const { | 2242 void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const { |
| 2222 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2243 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2223 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2244 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2224 assert(this->getSrcSize() == 2); | 2245 assert(this->getSrcSize() == 2); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2247 | 2268 |
| 2248 template <class Machine> | 2269 template <class Machine> |
| 2249 void InstX86StoreQ<Machine>::emit(const Cfg *Func) const { | 2270 void InstX86StoreQ<Machine>::emit(const Cfg *Func) const { |
| 2250 if (!BuildDefs::dump()) | 2271 if (!BuildDefs::dump()) |
| 2251 return; | 2272 return; |
| 2252 Ostream &Str = Func->getContext()->getStrEmit(); | 2273 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2253 assert(this->getSrcSize() == 2); | 2274 assert(this->getSrcSize() == 2); |
| 2254 assert(this->getSrc(1)->getType() == IceType_i64 || | 2275 assert(this->getSrc(1)->getType() == IceType_i64 || |
| 2255 this->getSrc(1)->getType() == IceType_f64 || | 2276 this->getSrc(1)->getType() == IceType_f64 || |
| 2256 isVectorType(this->getSrc(1)->getType())); | 2277 isVectorType(this->getSrc(1)->getType())); |
| 2257 Str << "\tmovq\t"; | 2278 Str << "\t" |
| 2279 "movq\t"; |
| 2258 this->getSrc(0)->emit(Func); | 2280 this->getSrc(0)->emit(Func); |
| 2259 Str << ", "; | 2281 Str << ", "; |
| 2260 this->getSrc(1)->emit(Func); | 2282 this->getSrc(1)->emit(Func); |
| 2261 } | 2283 } |
| 2262 | 2284 |
| 2263 template <class Machine> | 2285 template <class Machine> |
| 2264 void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const { | 2286 void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const { |
| 2265 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2287 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2266 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2288 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2267 assert(this->getSrcSize() == 2); | 2289 assert(this->getSrcSize() == 2); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2287 Str << ", "; | 2309 Str << ", "; |
| 2288 this->getSrc(0)->dump(Func); | 2310 this->getSrc(0)->dump(Func); |
| 2289 } | 2311 } |
| 2290 | 2312 |
| 2291 template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const { | 2313 template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const { |
| 2292 if (!BuildDefs::dump()) | 2314 if (!BuildDefs::dump()) |
| 2293 return; | 2315 return; |
| 2294 Ostream &Str = Func->getContext()->getStrEmit(); | 2316 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2295 assert(this->getSrcSize() == 1); | 2317 assert(this->getSrcSize() == 1); |
| 2296 assert(this->getDest()->hasReg()); | 2318 assert(this->getDest()->hasReg()); |
| 2297 Str << "\tleal\t"; | 2319 Str << "\t" |
| 2320 "leal\t"; |
| 2298 Operand *Src0 = this->getSrc(0); | 2321 Operand *Src0 = this->getSrc(0); |
| 2299 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { | 2322 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
| 2300 Type Ty = Src0Var->getType(); | 2323 Type Ty = Src0Var->getType(); |
| 2301 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 2324 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
| 2302 // acceptable type. | 2325 // acceptable type. |
| 2303 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister) | 2326 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister) |
| 2304 ->emit(Func); | 2327 ->emit(Func); |
| 2305 } else { | 2328 } else { |
| 2306 Src0->emit(Func); | 2329 Src0->emit(Func); |
| 2307 } | 2330 } |
| 2308 Str << ", "; | 2331 Str << ", "; |
| 2309 this->getDest()->emit(Func); | 2332 this->getDest()->emit(Func); |
| 2310 } | 2333 } |
| 2311 | 2334 |
| 2312 inline bool isIntegerConstant(const Operand *Op) { | 2335 inline bool isIntegerConstant(const Operand *Op) { |
| 2313 return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op); | 2336 return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op); |
| 2314 } | 2337 } |
| 2315 | 2338 |
| 2316 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { | 2339 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { |
| 2317 if (!BuildDefs::dump()) | 2340 if (!BuildDefs::dump()) |
| 2318 return; | 2341 return; |
| 2319 Ostream &Str = Func->getContext()->getStrEmit(); | 2342 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2320 assert(this->getSrcSize() == 1); | 2343 assert(this->getSrcSize() == 1); |
| 2321 Operand *Src = this->getSrc(0); | 2344 Operand *Src = this->getSrc(0); |
| 2322 Type SrcTy = Src->getType(); | 2345 Type SrcTy = Src->getType(); |
| 2323 Type DestTy = this->getDest()->getType(); | 2346 Type DestTy = this->getDest()->getType(); |
| 2324 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && | 2347 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| 2325 isIntegerConstant(Src)) { | 2348 isIntegerConstant(Src)) { |
| 2326 Str << "\tmovabs\t"; | 2349 Str << "\t" |
| 2350 "movabs\t"; |
| 2327 } else { | 2351 } else { |
| 2328 Str << "\tmov" | 2352 Str << "\t" |
| 2329 << (!isScalarFloatingType(DestTy) | 2353 "mov" << (!isScalarFloatingType(DestTy) |
| 2330 ? this->getWidthString(DestTy) | 2354 ? this->getWidthString(DestTy) |
| 2331 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] | 2355 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] |
| 2332 .SdSsString) << "\t"; | 2356 .SdSsString) << "\t"; |
| 2333 } | 2357 } |
| 2334 // For an integer truncation operation, src is wider than dest. In this case, | 2358 // For an integer truncation operation, src is wider than dest. In this case, |
| 2335 // we use a mov instruction whose data width matches the narrower dest. | 2359 // we use a mov instruction whose data width matches the narrower dest. |
| 2336 // TODO: This assert disallows usages such as copying a floating | 2360 // TODO: This assert disallows usages such as copying a floating |
| 2337 // point value between a vector and a scalar (which movss is used for). Clean | 2361 // point value between a vector and a scalar (which movss is used for). Clean |
| 2338 // this up. | 2362 // this up. |
| 2339 assert( | 2363 assert( |
| 2340 InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(DestTy) == | 2364 InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(DestTy) == |
| 2341 InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(SrcTy)); | 2365 InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(SrcTy)); |
| 2342 const Operand *NewSrc = Src; | 2366 const Operand *NewSrc = Src; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2492 | 2516 |
| 2493 template <class Machine> | 2517 template <class Machine> |
| 2494 void InstX86Movp<Machine>::emit(const Cfg *Func) const { | 2518 void InstX86Movp<Machine>::emit(const Cfg *Func) const { |
| 2495 if (!BuildDefs::dump()) | 2519 if (!BuildDefs::dump()) |
| 2496 return; | 2520 return; |
| 2497 // TODO(wala,stichnot): movups works with all vector operands, but there | 2521 // TODO(wala,stichnot): movups works with all vector operands, but there |
| 2498 // exist other instructions (movaps, movdqa, movdqu) that may perform better, | 2522 // exist other instructions (movaps, movdqa, movdqu) that may perform better, |
| 2499 // depending on the data type and alignment of the operands. | 2523 // depending on the data type and alignment of the operands. |
| 2500 Ostream &Str = Func->getContext()->getStrEmit(); | 2524 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2501 assert(this->getSrcSize() == 1); | 2525 assert(this->getSrcSize() == 1); |
| 2502 Str << "\tmovups\t"; | 2526 Str << "\t" |
| 2527 "movups\t"; |
| 2503 this->getSrc(0)->emit(Func); | 2528 this->getSrc(0)->emit(Func); |
| 2504 Str << ", "; | 2529 Str << ", "; |
| 2505 this->getDest()->emit(Func); | 2530 this->getDest()->emit(Func); |
| 2506 } | 2531 } |
| 2507 | 2532 |
| 2508 template <class Machine> | 2533 template <class Machine> |
| 2509 void InstX86Movp<Machine>::emitIAS(const Cfg *Func) const { | 2534 void InstX86Movp<Machine>::emitIAS(const Cfg *Func) const { |
| 2510 assert(this->getSrcSize() == 1); | 2535 assert(this->getSrcSize() == 1); |
| 2511 assert(isVectorType(this->getDest()->getType())); | 2536 assert(isVectorType(this->getDest()->getType())); |
| 2512 const Variable *Dest = this->getDest(); | 2537 const Variable *Dest = this->getDest(); |
| 2513 const Operand *Src = this->getSrc(0); | 2538 const Operand *Src = this->getSrc(0); |
| 2514 static const typename InstX86Base< | 2539 static const typename InstX86Base< |
| 2515 Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = { | 2540 Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = { |
| 2516 &InstX86Base<Machine>::Traits::Assembler::movups, | 2541 &InstX86Base<Machine>::Traits::Assembler::movups, |
| 2517 &InstX86Base<Machine>::Traits::Assembler::movups, | 2542 &InstX86Base<Machine>::Traits::Assembler::movups, |
| 2518 &InstX86Base<Machine>::Traits::Assembler::movups}; | 2543 &InstX86Base<Machine>::Traits::Assembler::movups}; |
| 2519 emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter); | 2544 emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter); |
| 2520 } | 2545 } |
| 2521 | 2546 |
| 2522 template <class Machine> | 2547 template <class Machine> |
| 2523 void InstX86Movq<Machine>::emit(const Cfg *Func) const { | 2548 void InstX86Movq<Machine>::emit(const Cfg *Func) const { |
| 2524 if (!BuildDefs::dump()) | 2549 if (!BuildDefs::dump()) |
| 2525 return; | 2550 return; |
| 2526 Ostream &Str = Func->getContext()->getStrEmit(); | 2551 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2527 assert(this->getSrcSize() == 1); | 2552 assert(this->getSrcSize() == 1); |
| 2528 assert(this->getDest()->getType() == IceType_i64 || | 2553 assert(this->getDest()->getType() == IceType_i64 || |
| 2529 this->getDest()->getType() == IceType_f64); | 2554 this->getDest()->getType() == IceType_f64); |
| 2530 Str << "\tmovq\t"; | 2555 Str << "\t" |
| 2556 "movq\t"; |
| 2531 this->getSrc(0)->emit(Func); | 2557 this->getSrc(0)->emit(Func); |
| 2532 Str << ", "; | 2558 Str << ", "; |
| 2533 this->getDest()->emit(Func); | 2559 this->getDest()->emit(Func); |
| 2534 } | 2560 } |
| 2535 | 2561 |
| 2536 template <class Machine> | 2562 template <class Machine> |
| 2537 void InstX86Movq<Machine>::emitIAS(const Cfg *Func) const { | 2563 void InstX86Movq<Machine>::emitIAS(const Cfg *Func) const { |
| 2538 assert(this->getSrcSize() == 1); | 2564 assert(this->getSrcSize() == 1); |
| 2539 assert(this->getDest()->getType() == IceType_i64 || | 2565 assert(this->getDest()->getType() == IceType_i64 || |
| 2540 this->getDest()->getType() == IceType_f64); | 2566 this->getDest()->getType() == IceType_f64); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2589 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); | 2615 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); |
| 2590 emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src, | 2616 emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src, |
| 2591 this->Emitter); | 2617 this->Emitter); |
| 2592 } | 2618 } |
| 2593 | 2619 |
| 2594 template <class Machine> void InstX86Nop<Machine>::emit(const Cfg *Func) const { | 2620 template <class Machine> void InstX86Nop<Machine>::emit(const Cfg *Func) const { |
| 2595 if (!BuildDefs::dump()) | 2621 if (!BuildDefs::dump()) |
| 2596 return; | 2622 return; |
| 2597 Ostream &Str = Func->getContext()->getStrEmit(); | 2623 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2598 // TODO: Emit the right code for each variant. | 2624 // TODO: Emit the right code for each variant. |
| 2599 Str << "\tnop\t# variant = " << Variant; | 2625 Str << "\t" |
| 2626 "nop\t# variant = " << Variant; |
| 2600 } | 2627 } |
| 2601 | 2628 |
| 2602 template <class Machine> | 2629 template <class Machine> |
| 2603 void InstX86Nop<Machine>::emitIAS(const Cfg *Func) const { | 2630 void InstX86Nop<Machine>::emitIAS(const Cfg *Func) const { |
| 2604 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2631 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2605 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2632 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2606 // TODO: Emit the right code for the variant. | 2633 // TODO: Emit the right code for the variant. |
| 2607 Asm->nop(); | 2634 Asm->nop(); |
| 2608 } | 2635 } |
| 2609 | 2636 |
| 2610 template <class Machine> void InstX86Nop<Machine>::dump(const Cfg *Func) const { | 2637 template <class Machine> void InstX86Nop<Machine>::dump(const Cfg *Func) const { |
| 2611 if (!BuildDefs::dump()) | 2638 if (!BuildDefs::dump()) |
| 2612 return; | 2639 return; |
| 2613 Ostream &Str = Func->getContext()->getStrDump(); | 2640 Ostream &Str = Func->getContext()->getStrDump(); |
| 2614 Str << "nop (variant = " << Variant << ")"; | 2641 Str << "nop (variant = " << Variant << ")"; |
| 2615 } | 2642 } |
| 2616 | 2643 |
| 2617 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const { | 2644 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const { |
| 2618 if (!BuildDefs::dump()) | 2645 if (!BuildDefs::dump()) |
| 2619 return; | 2646 return; |
| 2620 Ostream &Str = Func->getContext()->getStrEmit(); | 2647 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2621 assert(this->getSrcSize() == 1); | 2648 assert(this->getSrcSize() == 1); |
| 2622 Type Ty = this->getSrc(0)->getType(); | 2649 Type Ty = this->getSrc(0)->getType(); |
| 2623 const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0)); | 2650 const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0)); |
| 2624 if (Var && Var->hasReg()) { | 2651 if (Var && Var->hasReg()) { |
| 2625 // This is a physical xmm register, so we need to spill it to a temporary | 2652 // This is a physical xmm register, so we need to spill it to a temporary |
| 2626 // stack slot. Function prolog emission guarantees that there is sufficient | 2653 // stack slot. Function prolog emission guarantees that there is sufficient |
| 2627 // space to do this. | 2654 // space to do this. |
| 2628 Str << "\tmov" | 2655 Str << "\t" |
| 2629 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; | 2656 "mov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString |
| 2657 << "\t"; |
| 2630 Var->emit(Func); | 2658 Var->emit(Func); |
| 2631 Str << ", (%esp)\n"; | 2659 Str << ", (%esp)\n" |
| 2632 Str << "\tfld" << this->getFldString(Ty) << "\t" | 2660 "\t" |
| 2633 << "(%esp)"; | 2661 "fld" << this->getFldString(Ty) << "\t" |
| 2662 "(%esp)"; |
| 2634 return; | 2663 return; |
| 2635 } | 2664 } |
| 2636 Str << "\tfld" << this->getFldString(Ty) << "\t"; | 2665 Str << "\t" |
| 2666 "fld" << this->getFldString(Ty) << "\t"; |
| 2637 this->getSrc(0)->emit(Func); | 2667 this->getSrc(0)->emit(Func); |
| 2638 } | 2668 } |
| 2639 | 2669 |
| 2640 template <class Machine> | 2670 template <class Machine> |
| 2641 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const { | 2671 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const { |
| 2642 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2672 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2643 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2673 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2644 assert(this->getSrcSize() == 1); | 2674 assert(this->getSrcSize() == 1); |
| 2645 const Operand *Src = this->getSrc(0); | 2675 const Operand *Src = this->getSrc(0); |
| 2646 auto *Target = InstX86Base<Machine>::getTarget(Func); | 2676 auto *Target = InstX86Base<Machine>::getTarget(Func); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2685 template <class Machine> | 2715 template <class Machine> |
| 2686 void InstX86Fstp<Machine>::emit(const Cfg *Func) const { | 2716 void InstX86Fstp<Machine>::emit(const Cfg *Func) const { |
| 2687 if (!BuildDefs::dump()) | 2717 if (!BuildDefs::dump()) |
| 2688 return; | 2718 return; |
| 2689 Ostream &Str = Func->getContext()->getStrEmit(); | 2719 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2690 assert(this->getSrcSize() == 0); | 2720 assert(this->getSrcSize() == 0); |
| 2691 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2721 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
| 2692 // "partially" delete the fstp if the Dest is unused. Even if Dest is unused, | 2722 // "partially" delete the fstp if the Dest is unused. Even if Dest is unused, |
| 2693 // the fstp should be kept for the SideEffects of popping the stack. | 2723 // the fstp should be kept for the SideEffects of popping the stack. |
| 2694 if (!this->getDest()) { | 2724 if (!this->getDest()) { |
| 2695 Str << "\tfstp\tst(0)"; | 2725 Str << "\t" |
| 2726 "fstp\t" |
| 2727 "st(0)"; |
| 2696 return; | 2728 return; |
| 2697 } | 2729 } |
| 2698 Type Ty = this->getDest()->getType(); | 2730 Type Ty = this->getDest()->getType(); |
| 2699 if (!this->getDest()->hasReg()) { | 2731 if (!this->getDest()->hasReg()) { |
| 2700 Str << "\tfstp" << this->getFldString(Ty) << "\t"; | 2732 Str << "\t" |
| 2733 "fstp" << this->getFldString(Ty) << "\t"; |
| 2701 this->getDest()->emit(Func); | 2734 this->getDest()->emit(Func); |
| 2702 return; | 2735 return; |
| 2703 } | 2736 } |
| 2704 // Dest is a physical (xmm) register, so st(0) needs to go through memory. | 2737 // Dest is a physical (xmm) register, so st(0) needs to go through memory. |
| 2705 // Hack this by using caller-reserved memory at the top of stack, spilling | 2738 // Hack this by using caller-reserved memory at the top of stack, spilling |
| 2706 // st(0) there, and loading it into the xmm register. | 2739 // st(0) there, and loading it into the xmm register. |
| 2707 Str << "\tfstp" << this->getFldString(Ty) << "\t" | 2740 Str << "\t" |
| 2708 << "(%esp)\n"; | 2741 "fstp" << this->getFldString(Ty) << "\t" |
| 2709 Str << "\tmov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString | 2742 "(%esp)\n"; |
| 2743 Str << "\t" |
| 2744 "mov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString |
| 2710 << "\t" | 2745 << "\t" |
| 2711 << "(%esp), "; | 2746 "(%esp), "; |
| 2712 this->getDest()->emit(Func); | 2747 this->getDest()->emit(Func); |
| 2713 } | 2748 } |
| 2714 | 2749 |
| 2715 template <class Machine> | 2750 template <class Machine> |
| 2716 void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const { | 2751 void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const { |
| 2717 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2752 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2718 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2753 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2719 assert(this->getSrcSize() == 0); | 2754 assert(this->getSrcSize() == 0); |
| 2720 const Variable *Dest = this->getDest(); | 2755 const Variable *Dest = this->getDest(); |
| 2721 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2756 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2946 InstX86Base<Machine>::Traits::getEncodedXmm, | 2981 InstX86Base<Machine>::Traits::getEncodedXmm, |
| 2947 InstX86Base<Machine>::Traits::getEncodedXmm>( | 2982 InstX86Base<Machine>::Traits::getEncodedXmm>( |
| 2948 Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter); | 2983 Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter); |
| 2949 } | 2984 } |
| 2950 | 2985 |
| 2951 template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const { | 2986 template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const { |
| 2952 if (!BuildDefs::dump()) | 2987 if (!BuildDefs::dump()) |
| 2953 return; | 2988 return; |
| 2954 Ostream &Str = Func->getContext()->getStrEmit(); | 2989 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2955 assert(this->getSrcSize() == 0); | 2990 assert(this->getSrcSize() == 0); |
| 2956 Str << "\tpop\t"; | 2991 Str << "\t" |
| 2992 "pop\t"; |
| 2957 this->getDest()->emit(Func); | 2993 this->getDest()->emit(Func); |
| 2958 } | 2994 } |
| 2959 | 2995 |
| 2960 template <class Machine> | 2996 template <class Machine> |
| 2961 void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const { | 2997 void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const { |
| 2962 assert(this->getSrcSize() == 0); | 2998 assert(this->getSrcSize() == 0); |
| 2963 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2999 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2964 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3000 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2965 if (this->getDest()->hasReg()) { | 3001 if (this->getDest()->hasReg()) { |
| 2966 Asm->popl(InstX86Base<Machine>::Traits::getEncodedGPR( | 3002 Asm->popl(InstX86Base<Machine>::Traits::getEncodedGPR( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2981 | 3017 |
| 2982 template <class Machine> | 3018 template <class Machine> |
| 2983 void InstX86Push<Machine>::emit(const Cfg *Func) const { | 3019 void InstX86Push<Machine>::emit(const Cfg *Func) const { |
| 2984 if (!BuildDefs::dump()) | 3020 if (!BuildDefs::dump()) |
| 2985 return; | 3021 return; |
| 2986 Ostream &Str = Func->getContext()->getStrEmit(); | 3022 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2987 assert(this->getSrcSize() == 1); | 3023 assert(this->getSrcSize() == 1); |
| 2988 // Push is currently only used for saving GPRs. | 3024 // Push is currently only used for saving GPRs. |
| 2989 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); | 3025 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); |
| 2990 assert(Var->hasReg()); | 3026 assert(Var->hasReg()); |
| 2991 Str << "\tpush\t"; | 3027 Str << "\t" |
| 3028 "push\t"; |
| 2992 Var->emit(Func); | 3029 Var->emit(Func); |
| 2993 } | 3030 } |
| 2994 | 3031 |
| 2995 template <class Machine> | 3032 template <class Machine> |
| 2996 void InstX86Push<Machine>::emitIAS(const Cfg *Func) const { | 3033 void InstX86Push<Machine>::emitIAS(const Cfg *Func) const { |
| 2997 assert(this->getSrcSize() == 1); | 3034 assert(this->getSrcSize() == 1); |
| 2998 // Push is currently only used for saving GPRs. | 3035 // Push is currently only used for saving GPRs. |
| 2999 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); | 3036 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); |
| 3000 assert(Var->hasReg()); | 3037 assert(Var->hasReg()); |
| 3001 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3038 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3053 buf, llvm::array_lengthof(buf), "psrl%s", | 3090 buf, llvm::array_lengthof(buf), "psrl%s", |
| 3054 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | 3091 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] |
| 3055 .PackString); | 3092 .PackString); |
| 3056 this->emitTwoAddress(buf, this, Func); | 3093 this->emitTwoAddress(buf, this, Func); |
| 3057 } | 3094 } |
| 3058 | 3095 |
| 3059 template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const { | 3096 template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const { |
| 3060 if (!BuildDefs::dump()) | 3097 if (!BuildDefs::dump()) |
| 3061 return; | 3098 return; |
| 3062 Ostream &Str = Func->getContext()->getStrEmit(); | 3099 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3063 Str << "\tret"; | 3100 Str << "\t" |
| 3101 "ret"; |
| 3064 } | 3102 } |
| 3065 | 3103 |
| 3066 template <class Machine> | 3104 template <class Machine> |
| 3067 void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const { | 3105 void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const { |
| 3068 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3106 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3069 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3107 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3070 Asm->ret(); | 3108 Asm->ret(); |
| 3071 } | 3109 } |
| 3072 | 3110 |
| 3073 template <class Machine> void InstX86Ret<Machine>::dump(const Cfg *Func) const { | 3111 template <class Machine> void InstX86Ret<Machine>::dump(const Cfg *Func) const { |
| 3074 if (!BuildDefs::dump()) | 3112 if (!BuildDefs::dump()) |
| 3075 return; | 3113 return; |
| 3076 Ostream &Str = Func->getContext()->getStrDump(); | 3114 Ostream &Str = Func->getContext()->getStrDump(); |
| 3077 Type Ty = | 3115 Type Ty = |
| 3078 (this->getSrcSize() == 0 ? IceType_void : this->getSrc(0)->getType()); | 3116 (this->getSrcSize() == 0 ? IceType_void : this->getSrc(0)->getType()); |
| 3079 Str << "ret." << Ty << " "; | 3117 Str << "ret." << Ty << " "; |
| 3080 this->dumpSources(Func); | 3118 this->dumpSources(Func); |
| 3081 } | 3119 } |
| 3082 | 3120 |
| 3083 template <class Machine> | 3121 template <class Machine> |
| 3084 void InstX86Setcc<Machine>::emit(const Cfg *Func) const { | 3122 void InstX86Setcc<Machine>::emit(const Cfg *Func) const { |
| 3085 if (!BuildDefs::dump()) | 3123 if (!BuildDefs::dump()) |
| 3086 return; | 3124 return; |
| 3087 Ostream &Str = Func->getContext()->getStrEmit(); | 3125 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3088 Str << "\tset" | 3126 Str << "\t" |
| 3127 "set" |
| 3089 << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString | 3128 << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString |
| 3090 << "\t"; | 3129 << "\t"; |
| 3091 this->Dest->emit(Func); | 3130 this->Dest->emit(Func); |
| 3092 } | 3131 } |
| 3093 | 3132 |
| 3094 template <class Machine> | 3133 template <class Machine> |
| 3095 void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const { | 3134 void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const { |
| 3096 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); | 3135 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); |
| 3097 assert(this->getDest()->getType() == IceType_i1); | 3136 assert(this->getDest()->getType() == IceType_i1); |
| 3098 assert(this->getSrcSize() == 0); | 3137 assert(this->getSrcSize() == 0); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3117 << " "; | 3156 << " "; |
| 3118 this->dumpDest(Func); | 3157 this->dumpDest(Func); |
| 3119 } | 3158 } |
| 3120 | 3159 |
| 3121 template <class Machine> | 3160 template <class Machine> |
| 3122 void InstX86Xadd<Machine>::emit(const Cfg *Func) const { | 3161 void InstX86Xadd<Machine>::emit(const Cfg *Func) const { |
| 3123 if (!BuildDefs::dump()) | 3162 if (!BuildDefs::dump()) |
| 3124 return; | 3163 return; |
| 3125 Ostream &Str = Func->getContext()->getStrEmit(); | 3164 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3126 if (this->Locked) { | 3165 if (this->Locked) { |
| 3127 Str << "\tlock"; | 3166 Str << "\t" |
| 3167 "lock"; |
| 3128 } | 3168 } |
| 3129 Str << "\txadd" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; | 3169 Str << "\t" |
| 3170 "xadd" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 3130 this->getSrc(1)->emit(Func); | 3171 this->getSrc(1)->emit(Func); |
| 3131 Str << ", "; | 3172 Str << ", "; |
| 3132 this->getSrc(0)->emit(Func); | 3173 this->getSrc(0)->emit(Func); |
| 3133 } | 3174 } |
| 3134 | 3175 |
| 3135 template <class Machine> | 3176 template <class Machine> |
| 3136 void InstX86Xadd<Machine>::emitIAS(const Cfg *Func) const { | 3177 void InstX86Xadd<Machine>::emitIAS(const Cfg *Func) const { |
| 3137 assert(this->getSrcSize() == 2); | 3178 assert(this->getSrcSize() == 2); |
| 3138 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3179 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3139 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3180 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3164 Type Ty = this->getSrc(0)->getType(); | 3205 Type Ty = this->getSrc(0)->getType(); |
| 3165 Str << "xadd." << Ty << " "; | 3206 Str << "xadd." << Ty << " "; |
| 3166 this->dumpSources(Func); | 3207 this->dumpSources(Func); |
| 3167 } | 3208 } |
| 3168 | 3209 |
| 3169 template <class Machine> | 3210 template <class Machine> |
| 3170 void InstX86Xchg<Machine>::emit(const Cfg *Func) const { | 3211 void InstX86Xchg<Machine>::emit(const Cfg *Func) const { |
| 3171 if (!BuildDefs::dump()) | 3212 if (!BuildDefs::dump()) |
| 3172 return; | 3213 return; |
| 3173 Ostream &Str = Func->getContext()->getStrEmit(); | 3214 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3174 Str << "\txchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; | 3215 Str << "\t" |
| 3216 "xchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 3175 this->getSrc(1)->emit(Func); | 3217 this->getSrc(1)->emit(Func); |
| 3176 Str << ", "; | 3218 Str << ", "; |
| 3177 this->getSrc(0)->emit(Func); | 3219 this->getSrc(0)->emit(Func); |
| 3178 } | 3220 } |
| 3179 | 3221 |
| 3180 template <class Machine> | 3222 template <class Machine> |
| 3181 void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const { | 3223 void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const { |
| 3182 assert(this->getSrcSize() == 2); | 3224 assert(this->getSrcSize() == 2); |
| 3183 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3225 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3184 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3226 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3216 Str << "xchg." << Ty << " "; | 3258 Str << "xchg." << Ty << " "; |
| 3217 this->dumpSources(Func); | 3259 this->dumpSources(Func); |
| 3218 } | 3260 } |
| 3219 | 3261 |
| 3220 template <class Machine> | 3262 template <class Machine> |
| 3221 void InstX86IacaStart<Machine>::emit(const Cfg *Func) const { | 3263 void InstX86IacaStart<Machine>::emit(const Cfg *Func) const { |
| 3222 if (!BuildDefs::dump()) | 3264 if (!BuildDefs::dump()) |
| 3223 return; | 3265 return; |
| 3224 Ostream &Str = Func->getContext()->getStrEmit(); | 3266 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3225 Str << "\t# IACA_START\n" | 3267 Str << "\t# IACA_START\n" |
| 3226 << "\t.byte 0x0F, 0x0B\n" | 3268 "\t.byte 0x0F, 0x0B\n" |
| 3227 << "\tmovl\t$111, %ebx\n" | 3269 "\t" |
| 3228 << "\t.byte 0x64, 0x67, 0x90"; | 3270 "movl\t$111, %ebx\n" |
| 3271 "\t.byte 0x64, 0x67, 0x90"; |
| 3229 } | 3272 } |
| 3230 | 3273 |
| 3231 template <class Machine> | 3274 template <class Machine> |
| 3232 void InstX86IacaStart<Machine>::emitIAS(const Cfg *Func) const { | 3275 void InstX86IacaStart<Machine>::emitIAS(const Cfg *Func) const { |
| 3233 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3276 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3234 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3277 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3235 Asm->iaca_start(); | 3278 Asm->iaca_start(); |
| 3236 } | 3279 } |
| 3237 | 3280 |
| 3238 template <class Machine> | 3281 template <class Machine> |
| 3239 void InstX86IacaStart<Machine>::dump(const Cfg *Func) const { | 3282 void InstX86IacaStart<Machine>::dump(const Cfg *Func) const { |
| 3240 if (!BuildDefs::dump()) | 3283 if (!BuildDefs::dump()) |
| 3241 return; | 3284 return; |
| 3242 Ostream &Str = Func->getContext()->getStrDump(); | 3285 Ostream &Str = Func->getContext()->getStrDump(); |
| 3243 Str << "IACA_START"; | 3286 Str << "IACA_START"; |
| 3244 } | 3287 } |
| 3245 | 3288 |
| 3246 template <class Machine> | 3289 template <class Machine> |
| 3247 void InstX86IacaEnd<Machine>::emit(const Cfg *Func) const { | 3290 void InstX86IacaEnd<Machine>::emit(const Cfg *Func) const { |
| 3248 if (!BuildDefs::dump()) | 3291 if (!BuildDefs::dump()) |
| 3249 return; | 3292 return; |
| 3250 Ostream &Str = Func->getContext()->getStrEmit(); | 3293 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3251 Str << "\t# IACA_END\n" | 3294 Str << "\t# IACA_END\n" |
| 3252 << "\tmovl\t$222, %ebx\n" | 3295 "\t" |
| 3253 << "\t.byte 0x64, 0x67, 0x90\n" | 3296 "movl\t$222, %ebx\n" |
| 3254 << "\t.byte 0x0F, 0x0B"; | 3297 "\t.byte 0x64, 0x67, 0x90\n" |
| 3298 "\t.byte 0x0F, 0x0B"; |
| 3255 } | 3299 } |
| 3256 | 3300 |
| 3257 template <class Machine> | 3301 template <class Machine> |
| 3258 void InstX86IacaEnd<Machine>::emitIAS(const Cfg *Func) const { | 3302 void InstX86IacaEnd<Machine>::emitIAS(const Cfg *Func) const { |
| 3259 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3303 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3260 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3304 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3261 Asm->iaca_end(); | 3305 Asm->iaca_end(); |
| 3262 } | 3306 } |
| 3263 | 3307 |
| 3264 template <class Machine> | 3308 template <class Machine> |
| 3265 void InstX86IacaEnd<Machine>::dump(const Cfg *Func) const { | 3309 void InstX86IacaEnd<Machine>::dump(const Cfg *Func) const { |
| 3266 if (!BuildDefs::dump()) | 3310 if (!BuildDefs::dump()) |
| 3267 return; | 3311 return; |
| 3268 Ostream &Str = Func->getContext()->getStrDump(); | 3312 Ostream &Str = Func->getContext()->getStrDump(); |
| 3269 Str << "IACA_END"; | 3313 Str << "IACA_END"; |
| 3270 } | 3314 } |
| 3271 | 3315 |
| 3272 } // end of namespace X86Internal | 3316 } // end of namespace X86Internal |
| 3273 | 3317 |
| 3274 } // end of namespace Ice | 3318 } // end of namespace Ice |
| 3275 | 3319 |
| 3276 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3320 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |