| 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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 return; | 1245 return; |
| 1242 Ostream &Str = Func->getContext()->getStrEmit(); | 1246 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1243 assert(this->getSrcSize() == 2); | 1247 assert(this->getSrcSize() == 2); |
| 1244 Variable *Dest = this->getDest(); | 1248 Variable *Dest = this->getDest(); |
| 1245 if (isByteSizedArithType(Dest->getType())) { | 1249 if (isByteSizedArithType(Dest->getType())) { |
| 1246 // The 8-bit version of imul only allows the form "imul r/m8". | 1250 // The 8-bit version of imul only allows the form "imul r/m8". |
| 1247 const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0)); | 1251 const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0)); |
| 1248 (void)Src0Var; | 1252 (void)Src0Var; |
| 1249 assert(Src0Var->getRegNum() == | 1253 assert(Src0Var->getRegNum() == |
| 1250 InstX86Base<Machine>::Traits::RegisterSet::Reg_al); | 1254 InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
| 1251 Str << "\timulb\t"; | 1255 Str << "\t" |
| 1256 "imulb\t"; |
| 1252 this->getSrc(1)->emit(Func); | 1257 this->getSrc(1)->emit(Func); |
| 1253 } else if (llvm::isa<Constant>(this->getSrc(1))) { | 1258 } else if (llvm::isa<Constant>(this->getSrc(1))) { |
| 1254 Str << "\timul" << this->getWidthString(Dest->getType()) << "\t"; | 1259 Str << "\t" |
| 1260 "imul" << this->getWidthString(Dest->getType()) << "\t"; |
| 1255 this->getSrc(1)->emit(Func); | 1261 this->getSrc(1)->emit(Func); |
| 1256 Str << ", "; | 1262 Str << ", "; |
| 1257 this->getSrc(0)->emit(Func); | 1263 this->getSrc(0)->emit(Func); |
| 1258 Str << ", "; | 1264 Str << ", "; |
| 1259 Dest->emit(Func); | 1265 Dest->emit(Func); |
| 1260 } else { | 1266 } else { |
| 1261 this->emitTwoAddress("imul", this, Func); | 1267 this->emitTwoAddress("imul", this, Func); |
| 1262 } | 1268 } |
| 1263 } | 1269 } |
| 1264 | 1270 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1294 | 1300 |
| 1295 template <class Machine> | 1301 template <class Machine> |
| 1296 void InstX86ImulImm<Machine>::emit(const Cfg *Func) const { | 1302 void InstX86ImulImm<Machine>::emit(const Cfg *Func) const { |
| 1297 if (!BuildDefs::dump()) | 1303 if (!BuildDefs::dump()) |
| 1298 return; | 1304 return; |
| 1299 Ostream &Str = Func->getContext()->getStrEmit(); | 1305 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1300 assert(this->getSrcSize() == 2); | 1306 assert(this->getSrcSize() == 2); |
| 1301 Variable *Dest = this->getDest(); | 1307 Variable *Dest = this->getDest(); |
| 1302 assert(Dest->getType() == IceType_i16 || Dest->getType() == IceType_i32); | 1308 assert(Dest->getType() == IceType_i16 || Dest->getType() == IceType_i32); |
| 1303 assert(llvm::isa<Constant>(this->getSrc(1))); | 1309 assert(llvm::isa<Constant>(this->getSrc(1))); |
| 1304 Str << "\timul" << this->getWidthString(Dest->getType()) << "\t"; | 1310 Str << "\t" |
| 1311 "imul" << this->getWidthString(Dest->getType()) << "\t"; |
| 1305 this->getSrc(1)->emit(Func); | 1312 this->getSrc(1)->emit(Func); |
| 1306 Str << ", "; | 1313 Str << ", "; |
| 1307 this->getSrc(0)->emit(Func); | 1314 this->getSrc(0)->emit(Func); |
| 1308 Str << ", "; | 1315 Str << ", "; |
| 1309 Dest->emit(Func); | 1316 Dest->emit(Func); |
| 1310 } | 1317 } |
| 1311 | 1318 |
| 1312 template <class Machine> | 1319 template <class Machine> |
| 1313 void InstX86ImulImm<Machine>::emitIAS(const Cfg *Func) const { | 1320 void InstX86ImulImm<Machine>::emitIAS(const Cfg *Func) const { |
| 1314 assert(this->getSrcSize() == 2); | 1321 assert(this->getSrcSize() == 2); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 (void)SrcReg; | 1371 (void)SrcReg; |
| 1365 switch (Src0->getType()) { | 1372 switch (Src0->getType()) { |
| 1366 default: | 1373 default: |
| 1367 llvm_unreachable("unexpected source type!"); | 1374 llvm_unreachable("unexpected source type!"); |
| 1368 break; | 1375 break; |
| 1369 case IceType_i8: | 1376 case IceType_i8: |
| 1370 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_al); | 1377 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
| 1371 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax || | 1378 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax || |
| 1372 DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ah); | 1379 DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ah); |
| 1373 Str << "\t" | 1380 Str << "\t" |
| 1374 << "cbtw"; | 1381 "cbtw"; |
| 1375 break; | 1382 break; |
| 1376 case IceType_i16: | 1383 case IceType_i16: |
| 1377 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); | 1384 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
| 1378 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); | 1385 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); |
| 1379 Str << "\t" | 1386 Str << "\t" |
| 1380 << "cwtd"; | 1387 "cwtd"; |
| 1381 break; | 1388 break; |
| 1382 case IceType_i32: | 1389 case IceType_i32: |
| 1383 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1390 assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 1384 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1391 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1385 Str << "\t" | 1392 Str << "\t" |
| 1386 << "cltd"; | 1393 "cltd"; |
| 1387 break; | 1394 break; |
| 1388 case IceType_i64: | 1395 case IceType_i64: |
| 1389 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1396 assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1390 Str << "\t" | 1397 Str << "\t" |
| 1391 << "cdto"; | 1398 "cdto"; |
| 1392 break; | 1399 break; |
| 1393 } | 1400 } |
| 1394 } | 1401 } |
| 1395 | 1402 |
| 1396 template <class Machine> | 1403 template <class Machine> |
| 1397 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { | 1404 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { |
| 1398 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1405 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1399 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1406 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1400 assert(this->getSrcSize() == 1); | 1407 assert(this->getSrcSize() == 1); |
| 1401 Operand *Src0 = this->getSrc(0); | 1408 Operand *Src0 = this->getSrc(0); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1434 if (!BuildDefs::dump()) | 1441 if (!BuildDefs::dump()) |
| 1435 return; | 1442 return; |
| 1436 Ostream &Str = Func->getContext()->getStrEmit(); | 1443 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1437 assert(this->getSrcSize() == 2); | 1444 assert(this->getSrcSize() == 2); |
| 1438 assert(llvm::isa<Variable>(this->getSrc(0))); | 1445 assert(llvm::isa<Variable>(this->getSrc(0))); |
| 1439 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == | 1446 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == |
| 1440 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1447 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 1441 assert( | 1448 assert( |
| 1442 this->getDest()->getRegNum() == | 1449 this->getDest()->getRegNum() == |
| 1443 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx? | 1450 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx? |
| 1444 Str << "\tmul" << this->getWidthString(this->getDest()->getType()) << "\t"; | 1451 Str << "\t" |
| 1452 "mul" << this->getWidthString(this->getDest()->getType()) << "\t"; |
| 1445 this->getSrc(1)->emit(Func); | 1453 this->getSrc(1)->emit(Func); |
| 1446 } | 1454 } |
| 1447 | 1455 |
| 1448 template <class Machine> | 1456 template <class Machine> |
| 1449 void InstX86Mul<Machine>::emitIAS(const Cfg *Func) const { | 1457 void InstX86Mul<Machine>::emitIAS(const Cfg *Func) const { |
| 1450 assert(this->getSrcSize() == 2); | 1458 assert(this->getSrcSize() == 2); |
| 1451 assert(llvm::isa<Variable>(this->getSrc(0))); | 1459 assert(llvm::isa<Variable>(this->getSrc(0))); |
| 1452 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == | 1460 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == |
| 1453 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1461 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 1454 assert( | 1462 assert( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1472 } | 1480 } |
| 1473 | 1481 |
| 1474 template <class Machine> | 1482 template <class Machine> |
| 1475 void InstX86Shld<Machine>::emit(const Cfg *Func) const { | 1483 void InstX86Shld<Machine>::emit(const Cfg *Func) const { |
| 1476 if (!BuildDefs::dump()) | 1484 if (!BuildDefs::dump()) |
| 1477 return; | 1485 return; |
| 1478 Ostream &Str = Func->getContext()->getStrEmit(); | 1486 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1479 Variable *Dest = this->getDest(); | 1487 Variable *Dest = this->getDest(); |
| 1480 assert(this->getSrcSize() == 3); | 1488 assert(this->getSrcSize() == 3); |
| 1481 assert(Dest == this->getSrc(0)); | 1489 assert(Dest == this->getSrc(0)); |
| 1482 Str << "\tshld" << this->getWidthString(Dest->getType()) << "\t"; | 1490 Str << "\t" |
| 1491 "shld" << this->getWidthString(Dest->getType()) << "\t"; |
| 1483 this->getSrc(2)->emit(Func); | 1492 this->getSrc(2)->emit(Func); |
| 1484 Str << ", "; | 1493 Str << ", "; |
| 1485 this->getSrc(1)->emit(Func); | 1494 this->getSrc(1)->emit(Func); |
| 1486 Str << ", "; | 1495 Str << ", "; |
| 1487 Dest->emit(Func); | 1496 Dest->emit(Func); |
| 1488 } | 1497 } |
| 1489 | 1498 |
| 1490 template <class Machine> | 1499 template <class Machine> |
| 1491 void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const { | 1500 void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const { |
| 1492 assert(this->getSrcSize() == 3); | 1501 assert(this->getSrcSize() == 3); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1512 } | 1521 } |
| 1513 | 1522 |
| 1514 template <class Machine> | 1523 template <class Machine> |
| 1515 void InstX86Shrd<Machine>::emit(const Cfg *Func) const { | 1524 void InstX86Shrd<Machine>::emit(const Cfg *Func) const { |
| 1516 if (!BuildDefs::dump()) | 1525 if (!BuildDefs::dump()) |
| 1517 return; | 1526 return; |
| 1518 Ostream &Str = Func->getContext()->getStrEmit(); | 1527 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1519 Variable *Dest = this->getDest(); | 1528 Variable *Dest = this->getDest(); |
| 1520 assert(this->getSrcSize() == 3); | 1529 assert(this->getSrcSize() == 3); |
| 1521 assert(Dest == this->getSrc(0)); | 1530 assert(Dest == this->getSrc(0)); |
| 1522 Str << "\tshrd" << this->getWidthString(Dest->getType()) << "\t"; | 1531 Str << "\t" |
| 1532 "shrd" << this->getWidthString(Dest->getType()) << "\t"; |
| 1523 this->getSrc(2)->emit(Func); | 1533 this->getSrc(2)->emit(Func); |
| 1524 Str << ", "; | 1534 Str << ", "; |
| 1525 this->getSrc(1)->emit(Func); | 1535 this->getSrc(1)->emit(Func); |
| 1526 Str << ", "; | 1536 Str << ", "; |
| 1527 Dest->emit(Func); | 1537 Dest->emit(Func); |
| 1528 } | 1538 } |
| 1529 | 1539 |
| 1530 template <class Machine> | 1540 template <class Machine> |
| 1531 void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const { | 1541 void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const { |
| 1532 assert(this->getSrcSize() == 3); | 1542 assert(this->getSrcSize() == 3); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 this->dumpSources(Func); | 1627 this->dumpSources(Func); |
| 1618 } | 1628 } |
| 1619 | 1629 |
| 1620 template <class Machine> | 1630 template <class Machine> |
| 1621 void InstX86Cmpps<Machine>::emit(const Cfg *Func) const { | 1631 void InstX86Cmpps<Machine>::emit(const Cfg *Func) const { |
| 1622 if (!BuildDefs::dump()) | 1632 if (!BuildDefs::dump()) |
| 1623 return; | 1633 return; |
| 1624 Ostream &Str = Func->getContext()->getStrEmit(); | 1634 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1625 assert(this->getSrcSize() == 2); | 1635 assert(this->getSrcSize() == 2); |
| 1626 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); | 1636 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); |
| 1627 Str << "\t"; | 1637 Str << "\t" |
| 1628 Str << "cmp" | 1638 "cmp" |
| 1629 << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString | 1639 << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString |
| 1630 << "ps" | 1640 << "ps" |
| 1631 << "\t"; | 1641 "\t"; |
| 1632 this->getSrc(1)->emit(Func); | 1642 this->getSrc(1)->emit(Func); |
| 1633 Str << ", "; | 1643 Str << ", "; |
| 1634 this->getDest()->emit(Func); | 1644 this->getDest()->emit(Func); |
| 1635 } | 1645 } |
| 1636 | 1646 |
| 1637 template <class Machine> | 1647 template <class Machine> |
| 1638 void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const { | 1648 void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const { |
| 1639 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1649 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1640 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1650 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1641 assert(this->getSrcSize() == 2); | 1651 assert(this->getSrcSize() == 2); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1662 template <class Machine> | 1672 template <class Machine> |
| 1663 void InstX86Cmpps<Machine>::dump(const Cfg *Func) const { | 1673 void InstX86Cmpps<Machine>::dump(const Cfg *Func) const { |
| 1664 if (!BuildDefs::dump()) | 1674 if (!BuildDefs::dump()) |
| 1665 return; | 1675 return; |
| 1666 Ostream &Str = Func->getContext()->getStrDump(); | 1676 Ostream &Str = Func->getContext()->getStrDump(); |
| 1667 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); | 1677 assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid); |
| 1668 this->dumpDest(Func); | 1678 this->dumpDest(Func); |
| 1669 Str << " = cmp" | 1679 Str << " = cmp" |
| 1670 << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString | 1680 << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString |
| 1671 << "ps" | 1681 << "ps" |
| 1672 << "\t"; | 1682 "\t"; |
| 1673 this->dumpSources(Func); | 1683 this->dumpSources(Func); |
| 1674 } | 1684 } |
| 1675 | 1685 |
| 1676 template <class Machine> | 1686 template <class Machine> |
| 1677 void InstX86Cmpxchg<Machine>::emit(const Cfg *Func) const { | 1687 void InstX86Cmpxchg<Machine>::emit(const Cfg *Func) const { |
| 1678 if (!BuildDefs::dump()) | 1688 if (!BuildDefs::dump()) |
| 1679 return; | 1689 return; |
| 1680 Ostream &Str = Func->getContext()->getStrEmit(); | 1690 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1681 assert(this->getSrcSize() == 3); | 1691 assert(this->getSrcSize() == 3); |
| 1682 if (this->Locked) { | 1692 if (this->Locked) { |
| 1683 Str << "\tlock"; | 1693 Str << "\t" |
| 1694 "lock"; |
| 1684 } | 1695 } |
| 1685 Str << "\tcmpxchg" << this->getWidthString(this->getSrc(0)->getType()) | 1696 Str << "\t" |
| 1686 << "\t"; | 1697 "cmpxchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 1687 this->getSrc(2)->emit(Func); | 1698 this->getSrc(2)->emit(Func); |
| 1688 Str << ", "; | 1699 Str << ", "; |
| 1689 this->getSrc(0)->emit(Func); | 1700 this->getSrc(0)->emit(Func); |
| 1690 } | 1701 } |
| 1691 | 1702 |
| 1692 template <class Machine> | 1703 template <class Machine> |
| 1693 void InstX86Cmpxchg<Machine>::emitIAS(const Cfg *Func) const { | 1704 void InstX86Cmpxchg<Machine>::emitIAS(const Cfg *Func) const { |
| 1694 assert(this->getSrcSize() == 3); | 1705 assert(this->getSrcSize() == 3); |
| 1695 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1706 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1696 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1707 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1722 this->dumpSources(Func); | 1733 this->dumpSources(Func); |
| 1723 } | 1734 } |
| 1724 | 1735 |
| 1725 template <class Machine> | 1736 template <class Machine> |
| 1726 void InstX86Cmpxchg8b<Machine>::emit(const Cfg *Func) const { | 1737 void InstX86Cmpxchg8b<Machine>::emit(const Cfg *Func) const { |
| 1727 if (!BuildDefs::dump()) | 1738 if (!BuildDefs::dump()) |
| 1728 return; | 1739 return; |
| 1729 Ostream &Str = Func->getContext()->getStrEmit(); | 1740 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1730 assert(this->getSrcSize() == 5); | 1741 assert(this->getSrcSize() == 5); |
| 1731 if (this->Locked) { | 1742 if (this->Locked) { |
| 1732 Str << "\tlock"; | 1743 Str << "\t" |
| 1744 "lock"; |
| 1733 } | 1745 } |
| 1734 Str << "\tcmpxchg8b\t"; | 1746 Str << "\t" |
| 1747 "cmpxchg8b\t"; |
| 1735 this->getSrc(0)->emit(Func); | 1748 this->getSrc(0)->emit(Func); |
| 1736 } | 1749 } |
| 1737 | 1750 |
| 1738 template <class Machine> | 1751 template <class Machine> |
| 1739 void InstX86Cmpxchg8b<Machine>::emitIAS(const Cfg *Func) const { | 1752 void InstX86Cmpxchg8b<Machine>::emitIAS(const Cfg *Func) const { |
| 1740 assert(this->getSrcSize() == 5); | 1753 assert(this->getSrcSize() == 5); |
| 1741 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1754 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1742 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1755 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1743 const auto Mem = | 1756 const auto Mem = |
| 1744 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( | 1757 llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1761 } | 1774 } |
| 1762 Str << "cmpxchg8b "; | 1775 Str << "cmpxchg8b "; |
| 1763 this->dumpSources(Func); | 1776 this->dumpSources(Func); |
| 1764 } | 1777 } |
| 1765 | 1778 |
| 1766 template <class Machine> void InstX86Cvt<Machine>::emit(const Cfg *Func) const { | 1779 template <class Machine> void InstX86Cvt<Machine>::emit(const Cfg *Func) const { |
| 1767 if (!BuildDefs::dump()) | 1780 if (!BuildDefs::dump()) |
| 1768 return; | 1781 return; |
| 1769 Ostream &Str = Func->getContext()->getStrEmit(); | 1782 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1770 assert(this->getSrcSize() == 1); | 1783 assert(this->getSrcSize() == 1); |
| 1771 Str << "\tcvt"; | 1784 Str << "\t" |
| 1785 "cvt"; |
| 1772 if (isTruncating()) | 1786 if (isTruncating()) |
| 1773 Str << "t"; | 1787 Str << "t"; |
| 1774 Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) | 1788 Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) |
| 1775 ->getType()] | 1789 ->getType()] |
| 1776 .CvtString << "2" | 1790 .CvtString << "2" |
| 1777 << InstX86Base< | 1791 << InstX86Base< |
| 1778 Machine>::Traits::TypeAttributes[this->getDest()->getType()] | 1792 Machine>::Traits::TypeAttributes[this->getDest()->getType()] |
| 1779 .CvtString << "\t"; | 1793 .CvtString << "\t"; |
| 1780 this->getSrc(0)->emit(Func); | 1794 this->getSrc(0)->emit(Func); |
| 1781 Str << ", "; | 1795 Str << ", "; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 .CvtString << " "; | 1900 .CvtString << " "; |
| 1887 this->dumpSources(Func); | 1901 this->dumpSources(Func); |
| 1888 } | 1902 } |
| 1889 | 1903 |
| 1890 template <class Machine> | 1904 template <class Machine> |
| 1891 void InstX86Icmp<Machine>::emit(const Cfg *Func) const { | 1905 void InstX86Icmp<Machine>::emit(const Cfg *Func) const { |
| 1892 if (!BuildDefs::dump()) | 1906 if (!BuildDefs::dump()) |
| 1893 return; | 1907 return; |
| 1894 Ostream &Str = Func->getContext()->getStrEmit(); | 1908 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1895 assert(this->getSrcSize() == 2); | 1909 assert(this->getSrcSize() == 2); |
| 1896 Str << "\tcmp" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; | 1910 Str << "\t" |
| 1911 "cmp" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 1897 this->getSrc(1)->emit(Func); | 1912 this->getSrc(1)->emit(Func); |
| 1898 Str << ", "; | 1913 Str << ", "; |
| 1899 this->getSrc(0)->emit(Func); | 1914 this->getSrc(0)->emit(Func); |
| 1900 } | 1915 } |
| 1901 | 1916 |
| 1902 template <class Machine> | 1917 template <class Machine> |
| 1903 void InstX86Icmp<Machine>::emitIAS(const Cfg *Func) const { | 1918 void InstX86Icmp<Machine>::emitIAS(const Cfg *Func) const { |
| 1904 assert(this->getSrcSize() == 2); | 1919 assert(this->getSrcSize() == 2); |
| 1905 const Operand *Src0 = this->getSrc(0); | 1920 const Operand *Src0 = this->getSrc(0); |
| 1906 const Operand *Src1 = this->getSrc(1); | 1921 const Operand *Src1 = this->getSrc(1); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1930 Str << "cmp." << this->getSrc(0)->getType() << " "; | 1945 Str << "cmp." << this->getSrc(0)->getType() << " "; |
| 1931 this->dumpSources(Func); | 1946 this->dumpSources(Func); |
| 1932 } | 1947 } |
| 1933 | 1948 |
| 1934 template <class Machine> | 1949 template <class Machine> |
| 1935 void InstX86Ucomiss<Machine>::emit(const Cfg *Func) const { | 1950 void InstX86Ucomiss<Machine>::emit(const Cfg *Func) const { |
| 1936 if (!BuildDefs::dump()) | 1951 if (!BuildDefs::dump()) |
| 1937 return; | 1952 return; |
| 1938 Ostream &Str = Func->getContext()->getStrEmit(); | 1953 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1939 assert(this->getSrcSize() == 2); | 1954 assert(this->getSrcSize() == 2); |
| 1940 Str << "\tucomi" | 1955 Str << "\t" |
| 1956 "ucomi" |
| 1941 << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) | 1957 << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) |
| 1942 ->getType()] | 1958 ->getType()] |
| 1943 .SdSsString << "\t"; | 1959 .SdSsString << "\t"; |
| 1944 this->getSrc(1)->emit(Func); | 1960 this->getSrc(1)->emit(Func); |
| 1945 Str << ", "; | 1961 Str << ", "; |
| 1946 this->getSrc(0)->emit(Func); | 1962 this->getSrc(0)->emit(Func); |
| 1947 } | 1963 } |
| 1948 | 1964 |
| 1949 template <class Machine> | 1965 template <class Machine> |
| 1950 void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const { | 1966 void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1967 Ostream &Str = Func->getContext()->getStrDump(); | 1983 Ostream &Str = Func->getContext()->getStrDump(); |
| 1968 Str << "ucomiss." << this->getSrc(0)->getType() << " "; | 1984 Str << "ucomiss." << this->getSrc(0)->getType() << " "; |
| 1969 this->dumpSources(Func); | 1985 this->dumpSources(Func); |
| 1970 } | 1986 } |
| 1971 | 1987 |
| 1972 template <class Machine> void InstX86UD2<Machine>::emit(const Cfg *Func) const { | 1988 template <class Machine> void InstX86UD2<Machine>::emit(const Cfg *Func) const { |
| 1973 if (!BuildDefs::dump()) | 1989 if (!BuildDefs::dump()) |
| 1974 return; | 1990 return; |
| 1975 Ostream &Str = Func->getContext()->getStrEmit(); | 1991 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1976 assert(this->getSrcSize() == 0); | 1992 assert(this->getSrcSize() == 0); |
| 1977 Str << "\tud2"; | 1993 Str << "\t" |
| 1994 "ud2"; |
| 1978 } | 1995 } |
| 1979 | 1996 |
| 1980 template <class Machine> | 1997 template <class Machine> |
| 1981 void InstX86UD2<Machine>::emitIAS(const Cfg *Func) const { | 1998 void InstX86UD2<Machine>::emitIAS(const Cfg *Func) const { |
| 1982 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1999 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1983 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2000 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1984 Asm->ud2(); | 2001 Asm->ud2(); |
| 1985 } | 2002 } |
| 1986 | 2003 |
| 1987 template <class Machine> void InstX86UD2<Machine>::dump(const Cfg *Func) const { | 2004 template <class Machine> void InstX86UD2<Machine>::dump(const Cfg *Func) const { |
| 1988 if (!BuildDefs::dump()) | 2005 if (!BuildDefs::dump()) |
| 1989 return; | 2006 return; |
| 1990 Ostream &Str = Func->getContext()->getStrDump(); | 2007 Ostream &Str = Func->getContext()->getStrDump(); |
| 1991 Str << "ud2"; | 2008 Str << "ud2"; |
| 1992 } | 2009 } |
| 1993 | 2010 |
| 1994 template <class Machine> | 2011 template <class Machine> |
| 1995 void InstX86Test<Machine>::emit(const Cfg *Func) const { | 2012 void InstX86Test<Machine>::emit(const Cfg *Func) const { |
| 1996 if (!BuildDefs::dump()) | 2013 if (!BuildDefs::dump()) |
| 1997 return; | 2014 return; |
| 1998 Ostream &Str = Func->getContext()->getStrEmit(); | 2015 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1999 assert(this->getSrcSize() == 2); | 2016 assert(this->getSrcSize() == 2); |
| 2000 Str << "\ttest" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; | 2017 Str << "\t" |
| 2018 "test" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 2001 this->getSrc(1)->emit(Func); | 2019 this->getSrc(1)->emit(Func); |
| 2002 Str << ", "; | 2020 Str << ", "; |
| 2003 this->getSrc(0)->emit(Func); | 2021 this->getSrc(0)->emit(Func); |
| 2004 } | 2022 } |
| 2005 | 2023 |
| 2006 template <class Machine> | 2024 template <class Machine> |
| 2007 void InstX86Test<Machine>::emitIAS(const Cfg *Func) const { | 2025 void InstX86Test<Machine>::emitIAS(const Cfg *Func) const { |
| 2008 assert(this->getSrcSize() == 2); | 2026 assert(this->getSrcSize() == 2); |
| 2009 const Operand *Src0 = this->getSrc(0); | 2027 const Operand *Src0 = this->getSrc(0); |
| 2010 const Operand *Src1 = this->getSrc(1); | 2028 const Operand *Src1 = this->getSrc(1); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2034 Str << "test." << this->getSrc(0)->getType() << " "; | 2052 Str << "test." << this->getSrc(0)->getType() << " "; |
| 2035 this->dumpSources(Func); | 2053 this->dumpSources(Func); |
| 2036 } | 2054 } |
| 2037 | 2055 |
| 2038 template <class Machine> | 2056 template <class Machine> |
| 2039 void InstX86Mfence<Machine>::emit(const Cfg *Func) const { | 2057 void InstX86Mfence<Machine>::emit(const Cfg *Func) const { |
| 2040 if (!BuildDefs::dump()) | 2058 if (!BuildDefs::dump()) |
| 2041 return; | 2059 return; |
| 2042 Ostream &Str = Func->getContext()->getStrEmit(); | 2060 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2043 assert(this->getSrcSize() == 0); | 2061 assert(this->getSrcSize() == 0); |
| 2044 Str << "\tmfence"; | 2062 Str << "\t" |
| 2063 "mfence"; |
| 2045 } | 2064 } |
| 2046 | 2065 |
| 2047 template <class Machine> | 2066 template <class Machine> |
| 2048 void InstX86Mfence<Machine>::emitIAS(const Cfg *Func) const { | 2067 void InstX86Mfence<Machine>::emitIAS(const Cfg *Func) const { |
| 2049 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2068 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2050 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2069 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2051 Asm->mfence(); | 2070 Asm->mfence(); |
| 2052 } | 2071 } |
| 2053 | 2072 |
| 2054 template <class Machine> | 2073 template <class Machine> |
| 2055 void InstX86Mfence<Machine>::dump(const Cfg *Func) const { | 2074 void InstX86Mfence<Machine>::dump(const Cfg *Func) const { |
| 2056 if (!BuildDefs::dump()) | 2075 if (!BuildDefs::dump()) |
| 2057 return; | 2076 return; |
| 2058 Ostream &Str = Func->getContext()->getStrDump(); | 2077 Ostream &Str = Func->getContext()->getStrDump(); |
| 2059 Str << "mfence"; | 2078 Str << "mfence"; |
| 2060 } | 2079 } |
| 2061 | 2080 |
| 2062 template <class Machine> | 2081 template <class Machine> |
| 2063 void InstX86Store<Machine>::emit(const Cfg *Func) const { | 2082 void InstX86Store<Machine>::emit(const Cfg *Func) const { |
| 2064 if (!BuildDefs::dump()) | 2083 if (!BuildDefs::dump()) |
| 2065 return; | 2084 return; |
| 2066 Ostream &Str = Func->getContext()->getStrEmit(); | 2085 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2067 assert(this->getSrcSize() == 2); | 2086 assert(this->getSrcSize() == 2); |
| 2068 Type Ty = this->getSrc(0)->getType(); | 2087 Type Ty = this->getSrc(0)->getType(); |
| 2069 Str << "\tmov" << this->getWidthString(Ty) | 2088 Str << "\t" |
| 2089 "mov" << this->getWidthString(Ty) |
| 2070 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; | 2090 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; |
| 2071 this->getSrc(0)->emit(Func); | 2091 this->getSrc(0)->emit(Func); |
| 2072 Str << ", "; | 2092 Str << ", "; |
| 2073 this->getSrc(1)->emit(Func); | 2093 this->getSrc(1)->emit(Func); |
| 2074 } | 2094 } |
| 2075 | 2095 |
| 2076 template <class Machine> | 2096 template <class Machine> |
| 2077 void InstX86Store<Machine>::emitIAS(const Cfg *Func) const { | 2097 void InstX86Store<Machine>::emitIAS(const Cfg *Func) const { |
| 2078 assert(this->getSrcSize() == 2); | 2098 assert(this->getSrcSize() == 2); |
| 2079 const Operand *Dest = this->getSrc(1); | 2099 const Operand *Dest = this->getSrc(1); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2123 this->getSrc(0)->dump(Func); | 2143 this->getSrc(0)->dump(Func); |
| 2124 } | 2144 } |
| 2125 | 2145 |
| 2126 template <class Machine> | 2146 template <class Machine> |
| 2127 void InstX86StoreP<Machine>::emit(const Cfg *Func) const { | 2147 void InstX86StoreP<Machine>::emit(const Cfg *Func) const { |
| 2128 if (!BuildDefs::dump()) | 2148 if (!BuildDefs::dump()) |
| 2129 return; | 2149 return; |
| 2130 Ostream &Str = Func->getContext()->getStrEmit(); | 2150 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2131 assert(this->getSrcSize() == 2); | 2151 assert(this->getSrcSize() == 2); |
| 2132 assert(isVectorType(this->getSrc(1)->getType())); | 2152 assert(isVectorType(this->getSrc(1)->getType())); |
| 2133 Str << "\tmovups\t"; | 2153 Str << "\t" |
| 2154 "movups\t"; |
| 2134 this->getSrc(0)->emit(Func); | 2155 this->getSrc(0)->emit(Func); |
| 2135 Str << ", "; | 2156 Str << ", "; |
| 2136 this->getSrc(1)->emit(Func); | 2157 this->getSrc(1)->emit(Func); |
| 2137 } | 2158 } |
| 2138 | 2159 |
| 2139 template <class Machine> | 2160 template <class Machine> |
| 2140 void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const { | 2161 void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const { |
| 2141 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2162 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2142 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2163 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2143 assert(this->getSrcSize() == 2); | 2164 assert(this->getSrcSize() == 2); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2166 | 2187 |
| 2167 template <class Machine> | 2188 template <class Machine> |
| 2168 void InstX86StoreQ<Machine>::emit(const Cfg *Func) const { | 2189 void InstX86StoreQ<Machine>::emit(const Cfg *Func) const { |
| 2169 if (!BuildDefs::dump()) | 2190 if (!BuildDefs::dump()) |
| 2170 return; | 2191 return; |
| 2171 Ostream &Str = Func->getContext()->getStrEmit(); | 2192 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2172 assert(this->getSrcSize() == 2); | 2193 assert(this->getSrcSize() == 2); |
| 2173 assert(this->getSrc(1)->getType() == IceType_i64 || | 2194 assert(this->getSrc(1)->getType() == IceType_i64 || |
| 2174 this->getSrc(1)->getType() == IceType_f64 || | 2195 this->getSrc(1)->getType() == IceType_f64 || |
| 2175 isVectorType(this->getSrc(1)->getType())); | 2196 isVectorType(this->getSrc(1)->getType())); |
| 2176 Str << "\tmovq\t"; | 2197 Str << "\t" |
| 2198 "movq\t"; |
| 2177 this->getSrc(0)->emit(Func); | 2199 this->getSrc(0)->emit(Func); |
| 2178 Str << ", "; | 2200 Str << ", "; |
| 2179 this->getSrc(1)->emit(Func); | 2201 this->getSrc(1)->emit(Func); |
| 2180 } | 2202 } |
| 2181 | 2203 |
| 2182 template <class Machine> | 2204 template <class Machine> |
| 2183 void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const { | 2205 void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const { |
| 2184 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2206 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2185 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2207 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2186 assert(this->getSrcSize() == 2); | 2208 assert(this->getSrcSize() == 2); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2206 Str << ", "; | 2228 Str << ", "; |
| 2207 this->getSrc(0)->dump(Func); | 2229 this->getSrc(0)->dump(Func); |
| 2208 } | 2230 } |
| 2209 | 2231 |
| 2210 template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const { | 2232 template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const { |
| 2211 if (!BuildDefs::dump()) | 2233 if (!BuildDefs::dump()) |
| 2212 return; | 2234 return; |
| 2213 Ostream &Str = Func->getContext()->getStrEmit(); | 2235 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2214 assert(this->getSrcSize() == 1); | 2236 assert(this->getSrcSize() == 1); |
| 2215 assert(this->getDest()->hasReg()); | 2237 assert(this->getDest()->hasReg()); |
| 2216 Str << "\tleal\t"; | 2238 Str << "\t" |
| 2239 "leal\t"; |
| 2217 Operand *Src0 = this->getSrc(0); | 2240 Operand *Src0 = this->getSrc(0); |
| 2218 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { | 2241 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
| 2219 Type Ty = Src0Var->getType(); | 2242 Type Ty = Src0Var->getType(); |
| 2220 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 2243 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
| 2221 // acceptable type. | 2244 // acceptable type. |
| 2222 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister) | 2245 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister) |
| 2223 ->emit(Func); | 2246 ->emit(Func); |
| 2224 } else { | 2247 } else { |
| 2225 Src0->emit(Func); | 2248 Src0->emit(Func); |
| 2226 } | 2249 } |
| 2227 Str << ", "; | 2250 Str << ", "; |
| 2228 this->getDest()->emit(Func); | 2251 this->getDest()->emit(Func); |
| 2229 } | 2252 } |
| 2230 | 2253 |
| 2231 inline bool isIntegerConstant(const Operand *Op) { | 2254 inline bool isIntegerConstant(const Operand *Op) { |
| 2232 return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op); | 2255 return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op); |
| 2233 } | 2256 } |
| 2234 | 2257 |
| 2235 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { | 2258 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { |
| 2236 if (!BuildDefs::dump()) | 2259 if (!BuildDefs::dump()) |
| 2237 return; | 2260 return; |
| 2238 Ostream &Str = Func->getContext()->getStrEmit(); | 2261 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2239 assert(this->getSrcSize() == 1); | 2262 assert(this->getSrcSize() == 1); |
| 2240 Operand *Src = this->getSrc(0); | 2263 Operand *Src = this->getSrc(0); |
| 2241 Type SrcTy = Src->getType(); | 2264 Type SrcTy = Src->getType(); |
| 2242 Type DestTy = this->getDest()->getType(); | 2265 Type DestTy = this->getDest()->getType(); |
| 2243 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && | 2266 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| 2244 isIntegerConstant(Src)) { | 2267 isIntegerConstant(Src)) { |
| 2245 Str << "\tmovabs\t"; | 2268 Str << "\t" |
| 2269 "movabs\t"; |
| 2246 } else { | 2270 } else { |
| 2247 Str << "\tmov" | 2271 Str << "\t" |
| 2248 << (!isScalarFloatingType(DestTy) | 2272 "mov" << (!isScalarFloatingType(DestTy) |
| 2249 ? this->getWidthString(DestTy) | 2273 ? this->getWidthString(DestTy) |
| 2250 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] | 2274 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] |
| 2251 .SdSsString) << "\t"; | 2275 .SdSsString) << "\t"; |
| 2252 } | 2276 } |
| 2253 // For an integer truncation operation, src is wider than dest. In this case, | 2277 // For an integer truncation operation, src is wider than dest. In this case, |
| 2254 // we use a mov instruction whose data width matches the narrower dest. | 2278 // we use a mov instruction whose data width matches the narrower dest. |
| 2255 // TODO: This assert disallows usages such as copying a floating | 2279 // TODO: This assert disallows usages such as copying a floating |
| 2256 // point value between a vector and a scalar (which movss is used for). Clean | 2280 // point value between a vector and a scalar (which movss is used for). Clean |
| 2257 // this up. | 2281 // this up. |
| 2258 assert( | 2282 assert( |
| 2259 InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(DestTy) == | 2283 InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(DestTy) == |
| 2260 InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(SrcTy)); | 2284 InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(SrcTy)); |
| 2261 const Operand *NewSrc = Src; | 2285 const Operand *NewSrc = Src; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2411 | 2435 |
| 2412 template <class Machine> | 2436 template <class Machine> |
| 2413 void InstX86Movp<Machine>::emit(const Cfg *Func) const { | 2437 void InstX86Movp<Machine>::emit(const Cfg *Func) const { |
| 2414 if (!BuildDefs::dump()) | 2438 if (!BuildDefs::dump()) |
| 2415 return; | 2439 return; |
| 2416 // TODO(wala,stichnot): movups works with all vector operands, but there | 2440 // TODO(wala,stichnot): movups works with all vector operands, but there |
| 2417 // exist other instructions (movaps, movdqa, movdqu) that may perform better, | 2441 // exist other instructions (movaps, movdqa, movdqu) that may perform better, |
| 2418 // depending on the data type and alignment of the operands. | 2442 // depending on the data type and alignment of the operands. |
| 2419 Ostream &Str = Func->getContext()->getStrEmit(); | 2443 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2420 assert(this->getSrcSize() == 1); | 2444 assert(this->getSrcSize() == 1); |
| 2421 Str << "\tmovups\t"; | 2445 Str << "\t" |
| 2446 "movups\t"; |
| 2422 this->getSrc(0)->emit(Func); | 2447 this->getSrc(0)->emit(Func); |
| 2423 Str << ", "; | 2448 Str << ", "; |
| 2424 this->getDest()->emit(Func); | 2449 this->getDest()->emit(Func); |
| 2425 } | 2450 } |
| 2426 | 2451 |
| 2427 template <class Machine> | 2452 template <class Machine> |
| 2428 void InstX86Movp<Machine>::emitIAS(const Cfg *Func) const { | 2453 void InstX86Movp<Machine>::emitIAS(const Cfg *Func) const { |
| 2429 assert(this->getSrcSize() == 1); | 2454 assert(this->getSrcSize() == 1); |
| 2430 assert(isVectorType(this->getDest()->getType())); | 2455 assert(isVectorType(this->getDest()->getType())); |
| 2431 const Variable *Dest = this->getDest(); | 2456 const Variable *Dest = this->getDest(); |
| 2432 const Operand *Src = this->getSrc(0); | 2457 const Operand *Src = this->getSrc(0); |
| 2433 static const typename InstX86Base< | 2458 static const typename InstX86Base< |
| 2434 Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = { | 2459 Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = { |
| 2435 &InstX86Base<Machine>::Traits::Assembler::movups, | 2460 &InstX86Base<Machine>::Traits::Assembler::movups, |
| 2436 &InstX86Base<Machine>::Traits::Assembler::movups, | 2461 &InstX86Base<Machine>::Traits::Assembler::movups, |
| 2437 &InstX86Base<Machine>::Traits::Assembler::movups}; | 2462 &InstX86Base<Machine>::Traits::Assembler::movups}; |
| 2438 emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter); | 2463 emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter); |
| 2439 } | 2464 } |
| 2440 | 2465 |
| 2441 template <class Machine> | 2466 template <class Machine> |
| 2442 void InstX86Movq<Machine>::emit(const Cfg *Func) const { | 2467 void InstX86Movq<Machine>::emit(const Cfg *Func) const { |
| 2443 if (!BuildDefs::dump()) | 2468 if (!BuildDefs::dump()) |
| 2444 return; | 2469 return; |
| 2445 Ostream &Str = Func->getContext()->getStrEmit(); | 2470 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2446 assert(this->getSrcSize() == 1); | 2471 assert(this->getSrcSize() == 1); |
| 2447 assert(this->getDest()->getType() == IceType_i64 || | 2472 assert(this->getDest()->getType() == IceType_i64 || |
| 2448 this->getDest()->getType() == IceType_f64); | 2473 this->getDest()->getType() == IceType_f64); |
| 2449 Str << "\tmovq\t"; | 2474 Str << "\t" |
| 2475 "movq\t"; |
| 2450 this->getSrc(0)->emit(Func); | 2476 this->getSrc(0)->emit(Func); |
| 2451 Str << ", "; | 2477 Str << ", "; |
| 2452 this->getDest()->emit(Func); | 2478 this->getDest()->emit(Func); |
| 2453 } | 2479 } |
| 2454 | 2480 |
| 2455 template <class Machine> | 2481 template <class Machine> |
| 2456 void InstX86Movq<Machine>::emitIAS(const Cfg *Func) const { | 2482 void InstX86Movq<Machine>::emitIAS(const Cfg *Func) const { |
| 2457 assert(this->getSrcSize() == 1); | 2483 assert(this->getSrcSize() == 1); |
| 2458 assert(this->getDest()->getType() == IceType_i64 || | 2484 assert(this->getDest()->getType() == IceType_i64 || |
| 2459 this->getDest()->getType() == IceType_f64); | 2485 this->getDest()->getType() == IceType_f64); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2508 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); | 2534 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); |
| 2509 emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src, | 2535 emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src, |
| 2510 this->Emitter); | 2536 this->Emitter); |
| 2511 } | 2537 } |
| 2512 | 2538 |
| 2513 template <class Machine> void InstX86Nop<Machine>::emit(const Cfg *Func) const { | 2539 template <class Machine> void InstX86Nop<Machine>::emit(const Cfg *Func) const { |
| 2514 if (!BuildDefs::dump()) | 2540 if (!BuildDefs::dump()) |
| 2515 return; | 2541 return; |
| 2516 Ostream &Str = Func->getContext()->getStrEmit(); | 2542 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2517 // TODO: Emit the right code for each variant. | 2543 // TODO: Emit the right code for each variant. |
| 2518 Str << "\tnop\t# variant = " << Variant; | 2544 Str << "\t" |
| 2545 "nop\t# variant = " << Variant; |
| 2519 } | 2546 } |
| 2520 | 2547 |
| 2521 template <class Machine> | 2548 template <class Machine> |
| 2522 void InstX86Nop<Machine>::emitIAS(const Cfg *Func) const { | 2549 void InstX86Nop<Machine>::emitIAS(const Cfg *Func) const { |
| 2523 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2550 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2524 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2551 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2525 // TODO: Emit the right code for the variant. | 2552 // TODO: Emit the right code for the variant. |
| 2526 Asm->nop(); | 2553 Asm->nop(); |
| 2527 } | 2554 } |
| 2528 | 2555 |
| 2529 template <class Machine> void InstX86Nop<Machine>::dump(const Cfg *Func) const { | 2556 template <class Machine> void InstX86Nop<Machine>::dump(const Cfg *Func) const { |
| 2530 if (!BuildDefs::dump()) | 2557 if (!BuildDefs::dump()) |
| 2531 return; | 2558 return; |
| 2532 Ostream &Str = Func->getContext()->getStrDump(); | 2559 Ostream &Str = Func->getContext()->getStrDump(); |
| 2533 Str << "nop (variant = " << Variant << ")"; | 2560 Str << "nop (variant = " << Variant << ")"; |
| 2534 } | 2561 } |
| 2535 | 2562 |
| 2536 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const { | 2563 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const { |
| 2537 if (!BuildDefs::dump()) | 2564 if (!BuildDefs::dump()) |
| 2538 return; | 2565 return; |
| 2539 Ostream &Str = Func->getContext()->getStrEmit(); | 2566 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2540 assert(this->getSrcSize() == 1); | 2567 assert(this->getSrcSize() == 1); |
| 2541 Type Ty = this->getSrc(0)->getType(); | 2568 Type Ty = this->getSrc(0)->getType(); |
| 2542 const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0)); | 2569 const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0)); |
| 2543 if (Var && Var->hasReg()) { | 2570 if (Var && Var->hasReg()) { |
| 2544 // This is a physical xmm register, so we need to spill it to a temporary | 2571 // This is a physical xmm register, so we need to spill it to a temporary |
| 2545 // stack slot. Function prolog emission guarantees that there is sufficient | 2572 // stack slot. Function prolog emission guarantees that there is sufficient |
| 2546 // space to do this. | 2573 // space to do this. |
| 2547 Str << "\tmov" | 2574 Str << "\t" |
| 2548 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; | 2575 "mov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString |
| 2576 << "\t"; |
| 2549 Var->emit(Func); | 2577 Var->emit(Func); |
| 2550 Str << ", (%esp)\n"; | 2578 Str << ", (%esp)\n" |
| 2551 Str << "\tfld" << this->getFldString(Ty) << "\t" | 2579 "\t" |
| 2552 << "(%esp)"; | 2580 "fld" << this->getFldString(Ty) << "\t" |
| 2581 "(%esp)"; |
| 2553 return; | 2582 return; |
| 2554 } | 2583 } |
| 2555 Str << "\tfld" << this->getFldString(Ty) << "\t"; | 2584 Str << "\t" |
| 2585 "fld" << this->getFldString(Ty) << "\t"; |
| 2556 this->getSrc(0)->emit(Func); | 2586 this->getSrc(0)->emit(Func); |
| 2557 } | 2587 } |
| 2558 | 2588 |
| 2559 template <class Machine> | 2589 template <class Machine> |
| 2560 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const { | 2590 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const { |
| 2561 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2591 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2562 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2592 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2563 assert(this->getSrcSize() == 1); | 2593 assert(this->getSrcSize() == 1); |
| 2564 const Operand *Src = this->getSrc(0); | 2594 const Operand *Src = this->getSrc(0); |
| 2565 auto *Target = InstX86Base<Machine>::getTarget(Func); | 2595 auto *Target = InstX86Base<Machine>::getTarget(Func); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2604 template <class Machine> | 2634 template <class Machine> |
| 2605 void InstX86Fstp<Machine>::emit(const Cfg *Func) const { | 2635 void InstX86Fstp<Machine>::emit(const Cfg *Func) const { |
| 2606 if (!BuildDefs::dump()) | 2636 if (!BuildDefs::dump()) |
| 2607 return; | 2637 return; |
| 2608 Ostream &Str = Func->getContext()->getStrEmit(); | 2638 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2609 assert(this->getSrcSize() == 0); | 2639 assert(this->getSrcSize() == 0); |
| 2610 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2640 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
| 2611 // "partially" delete the fstp if the Dest is unused. Even if Dest is unused, | 2641 // "partially" delete the fstp if the Dest is unused. Even if Dest is unused, |
| 2612 // the fstp should be kept for the SideEffects of popping the stack. | 2642 // the fstp should be kept for the SideEffects of popping the stack. |
| 2613 if (!this->getDest()) { | 2643 if (!this->getDest()) { |
| 2614 Str << "\tfstp\tst(0)"; | 2644 Str << "\t" |
| 2645 "fstp\t" |
| 2646 "st(0)"; |
| 2615 return; | 2647 return; |
| 2616 } | 2648 } |
| 2617 Type Ty = this->getDest()->getType(); | 2649 Type Ty = this->getDest()->getType(); |
| 2618 if (!this->getDest()->hasReg()) { | 2650 if (!this->getDest()->hasReg()) { |
| 2619 Str << "\tfstp" << this->getFldString(Ty) << "\t"; | 2651 Str << "\t" |
| 2652 "fstp" << this->getFldString(Ty) << "\t"; |
| 2620 this->getDest()->emit(Func); | 2653 this->getDest()->emit(Func); |
| 2621 return; | 2654 return; |
| 2622 } | 2655 } |
| 2623 // Dest is a physical (xmm) register, so st(0) needs to go through memory. | 2656 // Dest is a physical (xmm) register, so st(0) needs to go through memory. |
| 2624 // Hack this by using caller-reserved memory at the top of stack, spilling | 2657 // Hack this by using caller-reserved memory at the top of stack, spilling |
| 2625 // st(0) there, and loading it into the xmm register. | 2658 // st(0) there, and loading it into the xmm register. |
| 2626 Str << "\tfstp" << this->getFldString(Ty) << "\t" | 2659 Str << "\t" |
| 2627 << "(%esp)\n"; | 2660 "fstp" << this->getFldString(Ty) << "\t" |
| 2628 Str << "\tmov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString | 2661 "(%esp)\n"; |
| 2662 Str << "\t" |
| 2663 "mov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString |
| 2629 << "\t" | 2664 << "\t" |
| 2630 << "(%esp), "; | 2665 "(%esp), "; |
| 2631 this->getDest()->emit(Func); | 2666 this->getDest()->emit(Func); |
| 2632 } | 2667 } |
| 2633 | 2668 |
| 2634 template <class Machine> | 2669 template <class Machine> |
| 2635 void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const { | 2670 void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const { |
| 2636 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2671 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2637 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2672 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2638 assert(this->getSrcSize() == 0); | 2673 assert(this->getSrcSize() == 0); |
| 2639 const Variable *Dest = this->getDest(); | 2674 const Variable *Dest = this->getDest(); |
| 2640 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2675 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2865 InstX86Base<Machine>::Traits::getEncodedXmm, | 2900 InstX86Base<Machine>::Traits::getEncodedXmm, |
| 2866 InstX86Base<Machine>::Traits::getEncodedXmm>( | 2901 InstX86Base<Machine>::Traits::getEncodedXmm>( |
| 2867 Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter); | 2902 Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter); |
| 2868 } | 2903 } |
| 2869 | 2904 |
| 2870 template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const { | 2905 template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const { |
| 2871 if (!BuildDefs::dump()) | 2906 if (!BuildDefs::dump()) |
| 2872 return; | 2907 return; |
| 2873 Ostream &Str = Func->getContext()->getStrEmit(); | 2908 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2874 assert(this->getSrcSize() == 0); | 2909 assert(this->getSrcSize() == 0); |
| 2875 Str << "\tpop\t"; | 2910 Str << "\t" |
| 2911 "pop\t"; |
| 2876 this->getDest()->emit(Func); | 2912 this->getDest()->emit(Func); |
| 2877 } | 2913 } |
| 2878 | 2914 |
| 2879 template <class Machine> | 2915 template <class Machine> |
| 2880 void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const { | 2916 void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const { |
| 2881 assert(this->getSrcSize() == 0); | 2917 assert(this->getSrcSize() == 0); |
| 2882 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2918 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2883 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2919 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2884 if (this->getDest()->hasReg()) { | 2920 if (this->getDest()->hasReg()) { |
| 2885 Asm->popl(InstX86Base<Machine>::Traits::getEncodedGPR( | 2921 Asm->popl(InstX86Base<Machine>::Traits::getEncodedGPR( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2900 | 2936 |
| 2901 template <class Machine> | 2937 template <class Machine> |
| 2902 void InstX86Push<Machine>::emit(const Cfg *Func) const { | 2938 void InstX86Push<Machine>::emit(const Cfg *Func) const { |
| 2903 if (!BuildDefs::dump()) | 2939 if (!BuildDefs::dump()) |
| 2904 return; | 2940 return; |
| 2905 Ostream &Str = Func->getContext()->getStrEmit(); | 2941 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2906 assert(this->getSrcSize() == 1); | 2942 assert(this->getSrcSize() == 1); |
| 2907 // Push is currently only used for saving GPRs. | 2943 // Push is currently only used for saving GPRs. |
| 2908 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); | 2944 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); |
| 2909 assert(Var->hasReg()); | 2945 assert(Var->hasReg()); |
| 2910 Str << "\tpush\t"; | 2946 Str << "\t" |
| 2947 "push\t"; |
| 2911 Var->emit(Func); | 2948 Var->emit(Func); |
| 2912 } | 2949 } |
| 2913 | 2950 |
| 2914 template <class Machine> | 2951 template <class Machine> |
| 2915 void InstX86Push<Machine>::emitIAS(const Cfg *Func) const { | 2952 void InstX86Push<Machine>::emitIAS(const Cfg *Func) const { |
| 2916 assert(this->getSrcSize() == 1); | 2953 assert(this->getSrcSize() == 1); |
| 2917 // Push is currently only used for saving GPRs. | 2954 // Push is currently only used for saving GPRs. |
| 2918 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); | 2955 const auto *Var = llvm::cast<Variable>(this->getSrc(0)); |
| 2919 assert(Var->hasReg()); | 2956 assert(Var->hasReg()); |
| 2920 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2957 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2972 buf, llvm::array_lengthof(buf), "psrl%s", | 3009 buf, llvm::array_lengthof(buf), "psrl%s", |
| 2973 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | 3010 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] |
| 2974 .PackString); | 3011 .PackString); |
| 2975 this->emitTwoAddress(buf, this, Func); | 3012 this->emitTwoAddress(buf, this, Func); |
| 2976 } | 3013 } |
| 2977 | 3014 |
| 2978 template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const { | 3015 template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const { |
| 2979 if (!BuildDefs::dump()) | 3016 if (!BuildDefs::dump()) |
| 2980 return; | 3017 return; |
| 2981 Ostream &Str = Func->getContext()->getStrEmit(); | 3018 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2982 Str << "\tret"; | 3019 Str << "\t" |
| 3020 "ret"; |
| 2983 } | 3021 } |
| 2984 | 3022 |
| 2985 template <class Machine> | 3023 template <class Machine> |
| 2986 void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const { | 3024 void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const { |
| 2987 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3025 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2988 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3026 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2989 Asm->ret(); | 3027 Asm->ret(); |
| 2990 } | 3028 } |
| 2991 | 3029 |
| 2992 template <class Machine> void InstX86Ret<Machine>::dump(const Cfg *Func) const { | 3030 template <class Machine> void InstX86Ret<Machine>::dump(const Cfg *Func) const { |
| 2993 if (!BuildDefs::dump()) | 3031 if (!BuildDefs::dump()) |
| 2994 return; | 3032 return; |
| 2995 Ostream &Str = Func->getContext()->getStrDump(); | 3033 Ostream &Str = Func->getContext()->getStrDump(); |
| 2996 Type Ty = | 3034 Type Ty = |
| 2997 (this->getSrcSize() == 0 ? IceType_void : this->getSrc(0)->getType()); | 3035 (this->getSrcSize() == 0 ? IceType_void : this->getSrc(0)->getType()); |
| 2998 Str << "ret." << Ty << " "; | 3036 Str << "ret." << Ty << " "; |
| 2999 this->dumpSources(Func); | 3037 this->dumpSources(Func); |
| 3000 } | 3038 } |
| 3001 | 3039 |
| 3002 template <class Machine> | 3040 template <class Machine> |
| 3003 void InstX86Setcc<Machine>::emit(const Cfg *Func) const { | 3041 void InstX86Setcc<Machine>::emit(const Cfg *Func) const { |
| 3004 if (!BuildDefs::dump()) | 3042 if (!BuildDefs::dump()) |
| 3005 return; | 3043 return; |
| 3006 Ostream &Str = Func->getContext()->getStrEmit(); | 3044 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3007 Str << "\tset" | 3045 Str << "\t" |
| 3046 "set" |
| 3008 << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString | 3047 << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString |
| 3009 << "\t"; | 3048 << "\t"; |
| 3010 this->Dest->emit(Func); | 3049 this->Dest->emit(Func); |
| 3011 } | 3050 } |
| 3012 | 3051 |
| 3013 template <class Machine> | 3052 template <class Machine> |
| 3014 void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const { | 3053 void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const { |
| 3015 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); | 3054 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); |
| 3016 assert(this->getDest()->getType() == IceType_i1); | 3055 assert(this->getDest()->getType() == IceType_i1); |
| 3017 assert(this->getSrcSize() == 0); | 3056 assert(this->getSrcSize() == 0); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3036 << " "; | 3075 << " "; |
| 3037 this->dumpDest(Func); | 3076 this->dumpDest(Func); |
| 3038 } | 3077 } |
| 3039 | 3078 |
| 3040 template <class Machine> | 3079 template <class Machine> |
| 3041 void InstX86Xadd<Machine>::emit(const Cfg *Func) const { | 3080 void InstX86Xadd<Machine>::emit(const Cfg *Func) const { |
| 3042 if (!BuildDefs::dump()) | 3081 if (!BuildDefs::dump()) |
| 3043 return; | 3082 return; |
| 3044 Ostream &Str = Func->getContext()->getStrEmit(); | 3083 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3045 if (this->Locked) { | 3084 if (this->Locked) { |
| 3046 Str << "\tlock"; | 3085 Str << "\t" |
| 3086 "lock"; |
| 3047 } | 3087 } |
| 3048 Str << "\txadd" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; | 3088 Str << "\t" |
| 3089 "xadd" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 3049 this->getSrc(1)->emit(Func); | 3090 this->getSrc(1)->emit(Func); |
| 3050 Str << ", "; | 3091 Str << ", "; |
| 3051 this->getSrc(0)->emit(Func); | 3092 this->getSrc(0)->emit(Func); |
| 3052 } | 3093 } |
| 3053 | 3094 |
| 3054 template <class Machine> | 3095 template <class Machine> |
| 3055 void InstX86Xadd<Machine>::emitIAS(const Cfg *Func) const { | 3096 void InstX86Xadd<Machine>::emitIAS(const Cfg *Func) const { |
| 3056 assert(this->getSrcSize() == 2); | 3097 assert(this->getSrcSize() == 2); |
| 3057 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3098 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3058 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3099 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3083 Type Ty = this->getSrc(0)->getType(); | 3124 Type Ty = this->getSrc(0)->getType(); |
| 3084 Str << "xadd." << Ty << " "; | 3125 Str << "xadd." << Ty << " "; |
| 3085 this->dumpSources(Func); | 3126 this->dumpSources(Func); |
| 3086 } | 3127 } |
| 3087 | 3128 |
| 3088 template <class Machine> | 3129 template <class Machine> |
| 3089 void InstX86Xchg<Machine>::emit(const Cfg *Func) const { | 3130 void InstX86Xchg<Machine>::emit(const Cfg *Func) const { |
| 3090 if (!BuildDefs::dump()) | 3131 if (!BuildDefs::dump()) |
| 3091 return; | 3132 return; |
| 3092 Ostream &Str = Func->getContext()->getStrEmit(); | 3133 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3093 Str << "\txchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; | 3134 Str << "\t" |
| 3135 "xchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t"; |
| 3094 this->getSrc(1)->emit(Func); | 3136 this->getSrc(1)->emit(Func); |
| 3095 Str << ", "; | 3137 Str << ", "; |
| 3096 this->getSrc(0)->emit(Func); | 3138 this->getSrc(0)->emit(Func); |
| 3097 } | 3139 } |
| 3098 | 3140 |
| 3099 template <class Machine> | 3141 template <class Machine> |
| 3100 void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const { | 3142 void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const { |
| 3101 assert(this->getSrcSize() == 2); | 3143 assert(this->getSrcSize() == 2); |
| 3102 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3144 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3103 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3145 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3135 Str << "xchg." << Ty << " "; | 3177 Str << "xchg." << Ty << " "; |
| 3136 this->dumpSources(Func); | 3178 this->dumpSources(Func); |
| 3137 } | 3179 } |
| 3138 | 3180 |
| 3139 template <class Machine> | 3181 template <class Machine> |
| 3140 void InstX86IacaStart<Machine>::emit(const Cfg *Func) const { | 3182 void InstX86IacaStart<Machine>::emit(const Cfg *Func) const { |
| 3141 if (!BuildDefs::dump()) | 3183 if (!BuildDefs::dump()) |
| 3142 return; | 3184 return; |
| 3143 Ostream &Str = Func->getContext()->getStrEmit(); | 3185 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3144 Str << "\t# IACA_START\n" | 3186 Str << "\t# IACA_START\n" |
| 3145 << "\t.byte 0x0F, 0x0B\n" | 3187 "\t.byte 0x0F, 0x0B\n" |
| 3146 << "\tmovl\t$111, %ebx\n" | 3188 "\t" |
| 3147 << "\t.byte 0x64, 0x67, 0x90"; | 3189 "movl\t$111, %ebx\n" |
| 3190 "\t.byte 0x64, 0x67, 0x90"; |
| 3148 } | 3191 } |
| 3149 | 3192 |
| 3150 template <class Machine> | 3193 template <class Machine> |
| 3151 void InstX86IacaStart<Machine>::emitIAS(const Cfg *Func) const { | 3194 void InstX86IacaStart<Machine>::emitIAS(const Cfg *Func) const { |
| 3152 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3195 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3153 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3196 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3154 Asm->iaca_start(); | 3197 Asm->iaca_start(); |
| 3155 } | 3198 } |
| 3156 | 3199 |
| 3157 template <class Machine> | 3200 template <class Machine> |
| 3158 void InstX86IacaStart<Machine>::dump(const Cfg *Func) const { | 3201 void InstX86IacaStart<Machine>::dump(const Cfg *Func) const { |
| 3159 if (!BuildDefs::dump()) | 3202 if (!BuildDefs::dump()) |
| 3160 return; | 3203 return; |
| 3161 Ostream &Str = Func->getContext()->getStrDump(); | 3204 Ostream &Str = Func->getContext()->getStrDump(); |
| 3162 Str << "IACA_START"; | 3205 Str << "IACA_START"; |
| 3163 } | 3206 } |
| 3164 | 3207 |
| 3165 template <class Machine> | 3208 template <class Machine> |
| 3166 void InstX86IacaEnd<Machine>::emit(const Cfg *Func) const { | 3209 void InstX86IacaEnd<Machine>::emit(const Cfg *Func) const { |
| 3167 if (!BuildDefs::dump()) | 3210 if (!BuildDefs::dump()) |
| 3168 return; | 3211 return; |
| 3169 Ostream &Str = Func->getContext()->getStrEmit(); | 3212 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3170 Str << "\t# IACA_END\n" | 3213 Str << "\t# IACA_END\n" |
| 3171 << "\tmovl\t$222, %ebx\n" | 3214 "\t" |
| 3172 << "\t.byte 0x64, 0x67, 0x90\n" | 3215 "movl\t$222, %ebx\n" |
| 3173 << "\t.byte 0x0F, 0x0B"; | 3216 "\t.byte 0x64, 0x67, 0x90\n" |
| 3217 "\t.byte 0x0F, 0x0B"; |
| 3174 } | 3218 } |
| 3175 | 3219 |
| 3176 template <class Machine> | 3220 template <class Machine> |
| 3177 void InstX86IacaEnd<Machine>::emitIAS(const Cfg *Func) const { | 3221 void InstX86IacaEnd<Machine>::emitIAS(const Cfg *Func) const { |
| 3178 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 3222 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 3179 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 3223 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 3180 Asm->iaca_end(); | 3224 Asm->iaca_end(); |
| 3181 } | 3225 } |
| 3182 | 3226 |
| 3183 template <class Machine> | 3227 template <class Machine> |
| 3184 void InstX86IacaEnd<Machine>::dump(const Cfg *Func) const { | 3228 void InstX86IacaEnd<Machine>::dump(const Cfg *Func) const { |
| 3185 if (!BuildDefs::dump()) | 3229 if (!BuildDefs::dump()) |
| 3186 return; | 3230 return; |
| 3187 Ostream &Str = Func->getContext()->getStrDump(); | 3231 Ostream &Str = Func->getContext()->getStrDump(); |
| 3188 Str << "IACA_END"; | 3232 Str << "IACA_END"; |
| 3189 } | 3233 } |
| 3190 | 3234 |
| 3191 } // end of namespace X86Internal | 3235 } // end of namespace X86Internal |
| 3192 | 3236 |
| 3193 } // end of namespace Ice | 3237 } // end of namespace Ice |
| 3194 | 3238 |
| 3195 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3239 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |