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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 : InstX86Base(Func, InstX86Base::Shrd, 3, Dest) { | 87 : InstX86Base(Func, InstX86Base::Shrd, 3, Dest) { |
88 this->addSource(Dest); | 88 this->addSource(Dest); |
89 this->addSource(Source1); | 89 this->addSource(Source1); |
90 this->addSource(Source2); | 90 this->addSource(Source2); |
91 } | 91 } |
92 | 92 |
93 template <typename TraitsType> | 93 template <typename TraitsType> |
94 InstImpl<TraitsType>::InstX86Label::InstX86Label(Cfg *Func, | 94 InstImpl<TraitsType>::InstX86Label::InstX86Label(Cfg *Func, |
95 TargetLowering *Target) | 95 TargetLowering *Target) |
96 : InstX86Base(Func, InstX86Base::Label, 0, nullptr), | 96 : InstX86Base(Func, InstX86Base::Label, 0, nullptr), |
97 Number(Target->makeNextLabelNumber()) {} | 97 LabelNumber(Target->makeNextLabelNumber()) { |
98 | 98 if (BuildDefs::dump()) { |
99 template <typename TraitsType> | 99 Name = GlobalString(Func->getContext(), ".L" + Func->getFunctionName() + |
100 IceString InstImpl<TraitsType>::InstX86Label::getName(const Cfg *Func) const { | 100 "$local$__" + |
101 // TODO(stichnot): Returning an empty string in a non-DUMP build can cause a | 101 std::to_string(LabelNumber)); |
102 // huge degradation in ConstantRelocatable hashing. Investigate and fix, but | 102 } else { |
103 // for now return something reasonably unique. | 103 Name = GlobalString(Func->getContext()); |
104 if (!BuildDefs::dump()) | 104 } |
105 return Func->getFunctionName() + std::to_string(Number); | |
106 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); | |
107 } | 105 } |
108 | 106 |
109 template <typename TraitsType> | 107 template <typename TraitsType> |
110 InstImpl<TraitsType>::InstX86Br::InstX86Br( | 108 InstImpl<TraitsType>::InstX86Br::InstX86Br( |
111 Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, | 109 Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, |
112 const InstImpl<TraitsType>::InstX86Label *Label, BrCond Condition, | 110 const InstImpl<TraitsType>::InstX86Label *Label, BrCond Condition, |
113 Mode Kind) | 111 Mode Kind) |
114 : InstX86Base(Func, InstX86Base::Br, 0, nullptr), Condition(Condition), | 112 : InstX86Base(Func, InstX86Base::Br, 0, nullptr), Condition(Condition), |
115 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label), | 113 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label), |
116 Kind(Kind) {} | 114 Kind(Kind) {} |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 Ostream &Str = Func->getContext()->getStrDump(); | 432 Ostream &Str = Func->getContext()->getStrDump(); |
435 this->getDest()->dump(Func); | 433 this->getDest()->dump(Func); |
436 Str << " = call getIP"; | 434 Str << " = call getIP"; |
437 } | 435 } |
438 | 436 |
439 template <typename TraitsType> | 437 template <typename TraitsType> |
440 void InstImpl<TraitsType>::InstX86Label::emit(const Cfg *Func) const { | 438 void InstImpl<TraitsType>::InstX86Label::emit(const Cfg *Func) const { |
441 if (!BuildDefs::dump()) | 439 if (!BuildDefs::dump()) |
442 return; | 440 return; |
443 Ostream &Str = Func->getContext()->getStrEmit(); | 441 Ostream &Str = Func->getContext()->getStrEmit(); |
444 Str << getName(Func) << ":"; | 442 Str << getLabelName() << ":"; |
445 } | 443 } |
446 | 444 |
447 template <typename TraitsType> | 445 template <typename TraitsType> |
448 void InstImpl<TraitsType>::InstX86Label::emitIAS(const Cfg *Func) const { | 446 void InstImpl<TraitsType>::InstX86Label::emitIAS(const Cfg *Func) const { |
449 Assembler *Asm = Func->getAssembler<Assembler>(); | 447 Assembler *Asm = Func->getAssembler<Assembler>(); |
450 Asm->bindLocalLabel(Number); | 448 Asm->bindLocalLabel(LabelNumber); |
451 if (OffsetReloc != nullptr) { | 449 if (OffsetReloc != nullptr) { |
452 Asm->bindRelocOffset(OffsetReloc); | 450 Asm->bindRelocOffset(OffsetReloc); |
453 } | 451 } |
454 } | 452 } |
455 | 453 |
456 template <typename TraitsType> | 454 template <typename TraitsType> |
457 void InstImpl<TraitsType>::InstX86Label::dump(const Cfg *Func) const { | 455 void InstImpl<TraitsType>::InstX86Label::dump(const Cfg *Func) const { |
458 if (!BuildDefs::dump()) | 456 if (!BuildDefs::dump()) |
459 return; | 457 return; |
460 Ostream &Str = Func->getContext()->getStrDump(); | 458 Ostream &Str = Func->getContext()->getStrDump(); |
461 Str << getName(Func) << ":"; | 459 Str << getLabelName() << ":"; |
462 } | 460 } |
463 | 461 |
464 template <typename TraitsType> | 462 template <typename TraitsType> |
465 void InstImpl<TraitsType>::InstX86Br::emit(const Cfg *Func) const { | 463 void InstImpl<TraitsType>::InstX86Br::emit(const Cfg *Func) const { |
466 if (!BuildDefs::dump()) | 464 if (!BuildDefs::dump()) |
467 return; | 465 return; |
468 Ostream &Str = Func->getContext()->getStrEmit(); | 466 Ostream &Str = Func->getContext()->getStrEmit(); |
469 Str << "\t"; | 467 Str << "\t"; |
470 | 468 |
471 if (Condition == Cond::Br_None) { | 469 if (Condition == Cond::Br_None) { |
472 Str << "jmp"; | 470 Str << "jmp"; |
473 } else { | 471 } else { |
474 Str << Traits::InstBrAttributes[Condition].EmitString; | 472 Str << Traits::InstBrAttributes[Condition].EmitString; |
475 } | 473 } |
476 | 474 |
477 if (Label) { | 475 if (Label) { |
478 Str << "\t" << Label->getName(Func); | 476 Str << "\t" << Label->getLabelName(); |
479 } else { | 477 } else { |
480 if (Condition == Cond::Br_None) { | 478 if (Condition == Cond::Br_None) { |
481 Str << "\t" << getTargetFalse()->getAsmName(); | 479 Str << "\t" << getTargetFalse()->getAsmName(); |
482 } else { | 480 } else { |
483 Str << "\t" << getTargetTrue()->getAsmName(); | 481 Str << "\t" << getTargetTrue()->getAsmName(); |
484 if (getTargetFalse()) { | 482 if (getTargetFalse()) { |
485 Str << "\n\t" | 483 Str << "\n\t" |
486 "jmp\t" << getTargetFalse()->getAsmName(); | 484 "jmp\t" << getTargetFalse()->getAsmName(); |
487 } | 485 } |
488 } | 486 } |
489 } | 487 } |
490 } | 488 } |
491 | 489 |
492 template <typename TraitsType> | 490 template <typename TraitsType> |
493 void InstImpl<TraitsType>::InstX86Br::emitIAS(const Cfg *Func) const { | 491 void InstImpl<TraitsType>::InstX86Br::emitIAS(const Cfg *Func) const { |
494 Assembler *Asm = Func->getAssembler<Assembler>(); | 492 Assembler *Asm = Func->getAssembler<Assembler>(); |
495 if (Label) { | 493 if (Label) { |
496 auto *L = Asm->getOrCreateLocalLabel(Label->getNumber()); | 494 auto *L = Asm->getOrCreateLocalLabel(Label->getLabelNumber()); |
497 if (Condition == Cond::Br_None) { | 495 if (Condition == Cond::Br_None) { |
498 Asm->jmp(L, isNear()); | 496 Asm->jmp(L, isNear()); |
499 } else { | 497 } else { |
500 Asm->j(Condition, L, isNear()); | 498 Asm->j(Condition, L, isNear()); |
501 } | 499 } |
502 } else { | 500 } else { |
503 if (Condition == Cond::Br_None) { | 501 if (Condition == Cond::Br_None) { |
504 auto *L = Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 502 auto *L = Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
505 assert(!getTargetTrue()); | 503 assert(!getTargetTrue()); |
506 Asm->jmp(L, isNear()); | 504 Asm->jmp(L, isNear()); |
507 } else { | 505 } else { |
508 auto *L = Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); | 506 auto *L = Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); |
509 Asm->j(Condition, L, isNear()); | 507 Asm->j(Condition, L, isNear()); |
510 if (getTargetFalse()) { | 508 if (getTargetFalse()) { |
511 auto *L2 = Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 509 auto *L2 = Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
512 Asm->jmp(L2, isNear()); | 510 Asm->jmp(L2, isNear()); |
513 } | 511 } |
514 } | 512 } |
515 } | 513 } |
516 } | 514 } |
517 | 515 |
518 template <typename TraitsType> | 516 template <typename TraitsType> |
519 void InstImpl<TraitsType>::InstX86Br::dump(const Cfg *Func) const { | 517 void InstImpl<TraitsType>::InstX86Br::dump(const Cfg *Func) const { |
520 if (!BuildDefs::dump()) | 518 if (!BuildDefs::dump()) |
521 return; | 519 return; |
522 Ostream &Str = Func->getContext()->getStrDump(); | 520 Ostream &Str = Func->getContext()->getStrDump(); |
523 Str << "br "; | 521 Str << "br "; |
524 | 522 |
525 if (Condition == Cond::Br_None) { | 523 if (Condition == Cond::Br_None) { |
526 Str << "label %" | 524 if (Label) { |
527 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); | 525 Str << "label %" << Label->getLabelName(); |
| 526 } else { |
| 527 Str << "label %" << getTargetFalse()->getName(); |
| 528 } |
528 return; | 529 return; |
529 } | 530 } |
530 | 531 |
531 Str << Traits::InstBrAttributes[Condition].DisplayString; | 532 Str << Traits::InstBrAttributes[Condition].DisplayString; |
532 if (Label) { | 533 if (Label) { |
533 Str << ", label %" << Label->getName(Func); | 534 Str << ", label %" << Label->getLabelName(); |
534 } else { | 535 } else { |
535 Str << ", label %" << getTargetTrue()->getName(); | 536 Str << ", label %" << getTargetTrue()->getName(); |
536 if (getTargetFalse()) { | 537 if (getTargetFalse()) { |
537 Str << ", label %" << getTargetFalse()->getName(); | 538 Str << ", label %" << getTargetFalse()->getName(); |
538 } | 539 } |
539 } | 540 } |
540 | 541 |
541 Str << " // (" << (isNear() ? "near" : "far") << " jump)"; | 542 Str << " // (" << (isNear() ? "near" : "far") << " jump)"; |
542 } | 543 } |
543 | 544 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 return; | 655 return; |
655 Ostream &Str = Func->getContext()->getStrDump(); | 656 Ostream &Str = Func->getContext()->getStrDump(); |
656 if (this->getDest()) { | 657 if (this->getDest()) { |
657 this->dumpDest(Func); | 658 this->dumpDest(Func); |
658 Str << " = "; | 659 Str << " = "; |
659 } | 660 } |
660 Str << "call "; | 661 Str << "call "; |
661 getCallTarget()->dump(Func); | 662 getCallTarget()->dump(Func); |
662 } | 663 } |
663 | 664 |
664 // The this->Opcode parameter needs to be char* and not IceString because of | 665 // The this->Opcode parameter needs to be char* and not std::string because of |
665 // template issues. | 666 // template issues. |
666 template <typename TraitsType> | 667 template <typename TraitsType> |
667 void InstImpl<TraitsType>::InstX86Base::emitTwoAddress( | 668 void InstImpl<TraitsType>::InstX86Base::emitTwoAddress( |
668 const Cfg *Func, const char *Opcode, const char *Suffix) const { | 669 const Cfg *Func, const char *Opcode, const char *Suffix) const { |
669 if (!BuildDefs::dump()) | 670 if (!BuildDefs::dump()) |
670 return; | 671 return; |
671 Ostream &Str = Func->getContext()->getStrEmit(); | 672 Ostream &Str = Func->getContext()->getStrEmit(); |
672 assert(getSrcSize() == 2); | 673 assert(getSrcSize() == 2); |
673 Operand *Dest = getDest(); | 674 Operand *Dest = getDest(); |
674 if (Dest == nullptr) | 675 if (Dest == nullptr) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 Address SrcStackAddr = Target->stackVarToAsmOperand(SrcVar); | 728 Address SrcStackAddr = Target->stackVarToAsmOperand(SrcVar); |
728 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 729 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
729 } | 730 } |
730 } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) { | 731 } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) { |
731 Mem->emitSegmentOverride(Asm); | 732 Mem->emitSegmentOverride(Asm); |
732 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, | 733 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, |
733 Mem->toAsmAddress(Asm, Target, IsLea)); | 734 Mem->toAsmAddress(Asm, Target, IsLea)); |
734 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 735 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
735 (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); | 736 (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); |
736 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 737 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
737 const auto FixupKind = Reloc->getName() == GlobalOffsetTable | 738 const auto FixupKind = (Reloc->getName().hasString() && |
| 739 Reloc->getName().toString() == GlobalOffsetTable) |
738 ? Traits::FK_GotPC | 740 ? Traits::FK_GotPC |
739 : Traits::TargetLowering::getAbsFixup(); | 741 : Traits::TargetLowering::getAbsFixup(); |
740 AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc); | 742 AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc); |
741 (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Fixup)); | 743 (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Fixup)); |
742 } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) { | 744 } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) { |
743 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 745 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
744 } else { | 746 } else { |
745 llvm_unreachable("Unexpected operand type"); | 747 llvm_unreachable("Unexpected operand type"); |
746 } | 748 } |
747 } | 749 } |
748 | 750 |
749 template <typename TraitsType> | 751 template <typename TraitsType> |
750 void InstImpl<TraitsType>::emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, | 752 void InstImpl<TraitsType>::emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, |
751 const Address &Addr, | 753 const Address &Addr, |
752 const Operand *Src, | 754 const Operand *Src, |
753 const GPREmitterAddrOp &Emitter) { | 755 const GPREmitterAddrOp &Emitter) { |
754 Assembler *Asm = Func->getAssembler<Assembler>(); | 756 Assembler *Asm = Func->getAssembler<Assembler>(); |
755 // Src can only be Reg or AssemblerImmediate. | 757 // Src can only be Reg or AssemblerImmediate. |
756 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 758 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
757 assert(SrcVar->hasReg()); | 759 assert(SrcVar->hasReg()); |
758 GPRRegister SrcReg = Traits::getEncodedGPR(SrcVar->getRegNum()); | 760 GPRRegister SrcReg = Traits::getEncodedGPR(SrcVar->getRegNum()); |
759 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 761 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
760 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 762 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
761 (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue())); | 763 (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue())); |
762 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 764 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
763 const auto FixupKind = Reloc->getName() == GlobalOffsetTable | 765 const auto FixupKind = (Reloc->getName().hasString() && |
| 766 Reloc->getName().toString() == GlobalOffsetTable) |
764 ? Traits::FK_GotPC | 767 ? Traits::FK_GotPC |
765 : Traits::TargetLowering::getAbsFixup(); | 768 : Traits::TargetLowering::getAbsFixup(); |
766 AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc); | 769 AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc); |
767 (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Fixup)); | 770 (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Fixup)); |
768 } else { | 771 } else { |
769 llvm_unreachable("Unexpected operand type"); | 772 llvm_unreachable("Unexpected operand type"); |
770 } | 773 } |
771 } | 774 } |
772 | 775 |
773 template <typename TraitsType> | 776 template <typename TraitsType> |
(...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1985 Ostream &Str = Func->getContext()->getStrEmit(); | 1988 Ostream &Str = Func->getContext()->getStrEmit(); |
1986 assert(this->getSrcSize() == 1); | 1989 assert(this->getSrcSize() == 1); |
1987 assert(this->getDest()->hasReg()); | 1990 assert(this->getDest()->hasReg()); |
1988 Str << "\t" | 1991 Str << "\t" |
1989 "lea" << this->getWidthString(this->getDest()->getType()) << "\t"; | 1992 "lea" << this->getWidthString(this->getDest()->getType()) << "\t"; |
1990 Operand *Src0 = this->getSrc(0); | 1993 Operand *Src0 = this->getSrc(0); |
1991 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { | 1994 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
1992 Type Ty = Src0Var->getType(); | 1995 Type Ty = Src0Var->getType(); |
1993 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 1996 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
1994 // acceptable type. | 1997 // acceptable type. |
1995 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, RegNumT())->emit(Func); | 1998 Src0Var->asType(Func, isVectorType(Ty) ? IceType_i32 : Ty, RegNumT()) |
| 1999 ->emit(Func); |
1996 } else { | 2000 } else { |
1997 Src0->emit(Func); | 2001 Src0->emit(Func); |
1998 } | 2002 } |
1999 Str << ", "; | 2003 Str << ", "; |
2000 this->getDest()->emit(Func); | 2004 this->getDest()->emit(Func); |
2001 } | 2005 } |
2002 | 2006 |
2003 template <typename TraitsType> | 2007 template <typename TraitsType> |
2004 void InstImpl<TraitsType>::InstX86Mov::emit(const Cfg *Func) const { | 2008 void InstImpl<TraitsType>::InstX86Mov::emit(const Cfg *Func) const { |
2005 if (!BuildDefs::dump()) | 2009 if (!BuildDefs::dump()) |
(...skipping 20 matching lines...) Expand all Loading... |
2026 // point value between a vector and a scalar (which movss is used for). Clean | 2030 // point value between a vector and a scalar (which movss is used for). Clean |
2027 // this up. | 2031 // this up. |
2028 assert(InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(DestTy) == | 2032 assert(InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(DestTy) == |
2029 InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(SrcTy)); | 2033 InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(SrcTy)); |
2030 const Operand *NewSrc = Src; | 2034 const Operand *NewSrc = Src; |
2031 if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 2035 if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
2032 RegNumT NewRegNum; | 2036 RegNumT NewRegNum; |
2033 if (SrcVar->hasReg()) | 2037 if (SrcVar->hasReg()) |
2034 NewRegNum = Traits::getGprForType(DestTy, SrcVar->getRegNum()); | 2038 NewRegNum = Traits::getGprForType(DestTy, SrcVar->getRegNum()); |
2035 if (SrcTy != DestTy) | 2039 if (SrcTy != DestTy) |
2036 NewSrc = SrcVar->asType(DestTy, NewRegNum); | 2040 NewSrc = SrcVar->asType(Func, DestTy, NewRegNum); |
2037 } | 2041 } |
2038 NewSrc->emit(Func); | 2042 NewSrc->emit(Func); |
2039 Str << ", "; | 2043 Str << ", "; |
2040 this->getDest()->emit(Func); | 2044 this->getDest()->emit(Func); |
2041 } | 2045 } |
2042 | 2046 |
2043 template <typename TraitsType> | 2047 template <typename TraitsType> |
2044 void InstImpl<TraitsType>::InstX86Mov::emitIAS(const Cfg *Func) const { | 2048 void InstImpl<TraitsType>::InstX86Mov::emitIAS(const Cfg *Func) const { |
2045 assert(this->getSrcSize() == 1); | 2049 assert(this->getSrcSize() == 1); |
2046 const Variable *Dest = this->getDest(); | 2050 const Variable *Dest = this->getDest(); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2304 if (Src->getType() == IceType_i32 && Dest->getType() == IceType_i64) { | 2308 if (Src->getType() == IceType_i32 && Dest->getType() == IceType_i64) { |
2305 Ostream &Str = Func->getContext()->getStrEmit(); | 2309 Ostream &Str = Func->getContext()->getStrEmit(); |
2306 if (mayBeElided(Dest, Src)) { | 2310 if (mayBeElided(Dest, Src)) { |
2307 Str << "\t/* elided movzx */"; | 2311 Str << "\t/* elided movzx */"; |
2308 } else { | 2312 } else { |
2309 Str << "\t" | 2313 Str << "\t" |
2310 "mov" | 2314 "mov" |
2311 "\t"; | 2315 "\t"; |
2312 Src->emit(Func); | 2316 Src->emit(Func); |
2313 Str << ", "; | 2317 Str << ", "; |
2314 Dest->asType(IceType_i32, | 2318 Dest->asType(Func, IceType_i32, |
2315 Traits::getGprForType(IceType_i32, Dest->getRegNum())) | 2319 Traits::getGprForType(IceType_i32, Dest->getRegNum())) |
2316 ->emit(Func); | 2320 ->emit(Func); |
2317 Str << " /* movzx */"; | 2321 Str << " /* movzx */"; |
2318 } | 2322 } |
2319 return; | 2323 return; |
2320 } | 2324 } |
2321 } | 2325 } |
2322 InstX86BaseUnaryopGPR<InstX86Base::Movzx>::emit(Func); | 2326 InstX86BaseUnaryopGPR<InstX86Base::Movzx>::emit(Func); |
2323 } | 2327 } |
2324 | 2328 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2512 << Traits::TypeAttributes[this->getSrc(0)->getType()].PackString << "\t"; | 2516 << Traits::TypeAttributes[this->getSrc(0)->getType()].PackString << "\t"; |
2513 this->getSrc(1)->emit(Func); | 2517 this->getSrc(1)->emit(Func); |
2514 Str << ", "; | 2518 Str << ", "; |
2515 this->getSrc(0)->emit(Func); | 2519 this->getSrc(0)->emit(Func); |
2516 Str << ", "; | 2520 Str << ", "; |
2517 Variable *Dest = this->getDest(); | 2521 Variable *Dest = this->getDest(); |
2518 // pextrw must take a register dest. There is an SSE4.1 version that takes a | 2522 // pextrw must take a register dest. There is an SSE4.1 version that takes a |
2519 // memory dest, but we aren't using it. For uniformity, just restrict them | 2523 // memory dest, but we aren't using it. For uniformity, just restrict them |
2520 // all to have a register dest for now. | 2524 // all to have a register dest for now. |
2521 assert(Dest->hasReg()); | 2525 assert(Dest->hasReg()); |
2522 Dest->asType(IceType_i32, Dest->getRegNum())->emit(Func); | 2526 Dest->asType(Func, IceType_i32, Dest->getRegNum())->emit(Func); |
2523 } | 2527 } |
2524 | 2528 |
2525 template <typename TraitsType> | 2529 template <typename TraitsType> |
2526 void InstImpl<TraitsType>::InstX86Pextr::emitIAS(const Cfg *Func) const { | 2530 void InstImpl<TraitsType>::InstX86Pextr::emitIAS(const Cfg *Func) const { |
2527 assert(this->getSrcSize() == 2); | 2531 assert(this->getSrcSize() == 2); |
2528 // pextrb and pextrd are SSE4.1 instructions. | 2532 // pextrb and pextrd are SSE4.1 instructions. |
2529 const Variable *Dest = this->getDest(); | 2533 const Variable *Dest = this->getDest(); |
2530 Type DispatchTy = Traits::getInVectorElementType(this->getSrc(0)->getType()); | 2534 Type DispatchTy = Traits::getInVectorElementType(this->getSrc(0)->getType()); |
2531 // pextrw must take a register dest. There is an SSE4.1 version that takes a | 2535 // pextrw must take a register dest. There is an SSE4.1 version that takes a |
2532 // memory dest, but we aren't using it. For uniformity, just restrict them | 2536 // memory dest, but we aren't using it. For uniformity, just restrict them |
(...skipping 16 matching lines...) Expand all Loading... |
2549 assert(this->getSrcSize() == 3); | 2553 assert(this->getSrcSize() == 3); |
2550 Str << "\t" << this->Opcode | 2554 Str << "\t" << this->Opcode |
2551 << Traits::TypeAttributes[this->getDest()->getType()].PackString << "\t"; | 2555 << Traits::TypeAttributes[this->getDest()->getType()].PackString << "\t"; |
2552 this->getSrc(2)->emit(Func); | 2556 this->getSrc(2)->emit(Func); |
2553 Str << ", "; | 2557 Str << ", "; |
2554 Operand *Src1 = this->getSrc(1); | 2558 Operand *Src1 = this->getSrc(1); |
2555 if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) { | 2559 if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) { |
2556 // If src1 is a register, it should always be r32. | 2560 // If src1 is a register, it should always be r32. |
2557 if (Src1Var->hasReg()) { | 2561 if (Src1Var->hasReg()) { |
2558 const auto NewRegNum = Traits::getBaseReg(Src1Var->getRegNum()); | 2562 const auto NewRegNum = Traits::getBaseReg(Src1Var->getRegNum()); |
2559 const Variable *NewSrc = Src1Var->asType(IceType_i32, NewRegNum); | 2563 const Variable *NewSrc = Src1Var->asType(Func, IceType_i32, NewRegNum); |
2560 NewSrc->emit(Func); | 2564 NewSrc->emit(Func); |
2561 } else { | 2565 } else { |
2562 Src1Var->emit(Func); | 2566 Src1Var->emit(Func); |
2563 } | 2567 } |
2564 } else { | 2568 } else { |
2565 Src1->emit(Func); | 2569 Src1->emit(Func); |
2566 } | 2570 } |
2567 Str << ", "; | 2571 Str << ", "; |
2568 this->getDest()->emit(Func); | 2572 this->getDest()->emit(Func); |
2569 } | 2573 } |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2893 return; | 2897 return; |
2894 Ostream &Str = Func->getContext()->getStrDump(); | 2898 Ostream &Str = Func->getContext()->getStrDump(); |
2895 Str << "IACA_END"; | 2899 Str << "IACA_END"; |
2896 } | 2900 } |
2897 | 2901 |
2898 } // end of namespace X86NAMESPACE | 2902 } // end of namespace X86NAMESPACE |
2899 | 2903 |
2900 } // end of namespace Ice | 2904 } // end of namespace Ice |
2901 | 2905 |
2902 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 2906 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
OLD | NEW |