| OLD | NEW |
| 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 } | 364 } |
| 365 | 365 |
| 366 void InstX8632Label::emit(const Cfg *Func) const { | 366 void InstX8632Label::emit(const Cfg *Func) const { |
| 367 if (!ALLOW_DUMP) | 367 if (!ALLOW_DUMP) |
| 368 return; | 368 return; |
| 369 Ostream &Str = Func->getContext()->getStrEmit(); | 369 Ostream &Str = Func->getContext()->getStrEmit(); |
| 370 Str << getName(Func) << ":"; | 370 Str << getName(Func) << ":"; |
| 371 } | 371 } |
| 372 | 372 |
| 373 void InstX8632Label::emitIAS(const Cfg *Func) const { | 373 void InstX8632Label::emitIAS(const Cfg *Func) const { |
| 374 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 374 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 375 Asm->BindLocalLabel(Number); | 375 Asm->BindLocalLabel(Number); |
| 376 } | 376 } |
| 377 | 377 |
| 378 void InstX8632Label::dump(const Cfg *Func) const { | 378 void InstX8632Label::dump(const Cfg *Func) const { |
| 379 if (!ALLOW_DUMP) | 379 if (!ALLOW_DUMP) |
| 380 return; | 380 return; |
| 381 Ostream &Str = Func->getContext()->getStrDump(); | 381 Ostream &Str = Func->getContext()->getStrDump(); |
| 382 Str << getName(Func) << ":"; | 382 Str << getName(Func) << ":"; |
| 383 } | 383 } |
| 384 | 384 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 402 } else { | 402 } else { |
| 403 Str << "\t" << getTargetTrue()->getAsmName(); | 403 Str << "\t" << getTargetTrue()->getAsmName(); |
| 404 if (getTargetFalse()) { | 404 if (getTargetFalse()) { |
| 405 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); | 405 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); |
| 406 } | 406 } |
| 407 } | 407 } |
| 408 } | 408 } |
| 409 } | 409 } |
| 410 | 410 |
| 411 void InstX8632Br::emitIAS(const Cfg *Func) const { | 411 void InstX8632Br::emitIAS(const Cfg *Func) const { |
| 412 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 412 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 413 if (Label) { | 413 if (Label) { |
| 414 x86::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); | 414 X8632::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); |
| 415 // In all these cases, local Labels should only be used for Near. | 415 // In all these cases, local Labels should only be used for Near. |
| 416 const bool Near = true; | 416 const bool Near = true; |
| 417 if (Condition == CondX86::Br_None) { | 417 if (Condition == CondX86::Br_None) { |
| 418 Asm->jmp(L, Near); | 418 Asm->jmp(L, Near); |
| 419 } else { | 419 } else { |
| 420 Asm->j(Condition, L, Near); | 420 Asm->j(Condition, L, Near); |
| 421 } | 421 } |
| 422 } else { | 422 } else { |
| 423 // Pessimistically assume it's far. This only affects Labels that | 423 // Pessimistically assume it's far. This only affects Labels that |
| 424 // are not Bound. | 424 // are not Bound. |
| 425 const bool Near = false; | 425 const bool Near = false; |
| 426 if (Condition == CondX86::Br_None) { | 426 if (Condition == CondX86::Br_None) { |
| 427 x86::Label *L = | 427 X8632::Label *L = |
| 428 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 428 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
| 429 assert(!getTargetTrue()); | 429 assert(!getTargetTrue()); |
| 430 Asm->jmp(L, Near); | 430 Asm->jmp(L, Near); |
| 431 } else { | 431 } else { |
| 432 x86::Label *L = Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); | 432 X8632::Label *L = |
| 433 Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); |
| 433 Asm->j(Condition, L, Near); | 434 Asm->j(Condition, L, Near); |
| 434 if (getTargetFalse()) { | 435 if (getTargetFalse()) { |
| 435 x86::Label *L2 = | 436 X8632::Label *L2 = |
| 436 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 437 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
| 437 Asm->jmp(L2, Near); | 438 Asm->jmp(L2, Near); |
| 438 } | 439 } |
| 439 } | 440 } |
| 440 } | 441 } |
| 441 } | 442 } |
| 442 | 443 |
| 443 void InstX8632Br::dump(const Cfg *Func) const { | 444 void InstX8632Br::dump(const Cfg *Func) const { |
| 444 if (!ALLOW_DUMP) | 445 if (!ALLOW_DUMP) |
| 445 return; | 446 return; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 467 if (!ALLOW_DUMP) | 468 if (!ALLOW_DUMP) |
| 468 return; | 469 return; |
| 469 Ostream &Str = Func->getContext()->getStrEmit(); | 470 Ostream &Str = Func->getContext()->getStrEmit(); |
| 470 assert(getSrcSize() == 1); | 471 assert(getSrcSize() == 1); |
| 471 Str << "\tjmp\t*"; | 472 Str << "\tjmp\t*"; |
| 472 getJmpTarget()->emit(Func); | 473 getJmpTarget()->emit(Func); |
| 473 } | 474 } |
| 474 | 475 |
| 475 void InstX8632Jmp::emitIAS(const Cfg *Func) const { | 476 void InstX8632Jmp::emitIAS(const Cfg *Func) const { |
| 476 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). | 477 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). |
| 477 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 478 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 478 Operand *Target = getJmpTarget(); | 479 Operand *Target = getJmpTarget(); |
| 479 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 480 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { |
| 480 if (Var->hasReg()) { | 481 if (Var->hasReg()) { |
| 481 Asm->jmp(RegX8632::getEncodedGPR(Var->getRegNum())); | 482 Asm->jmp(RegX8632::getEncodedGPR(Var->getRegNum())); |
| 482 } else { | 483 } else { |
| 483 // The jmp instruction with a memory operand should be possible | 484 // The jmp instruction with a memory operand should be possible |
| 484 // to encode, but it isn't a valid sandboxed instruction, and | 485 // to encode, but it isn't a valid sandboxed instruction, and |
| 485 // there shouldn't be a register allocation issue to jump | 486 // there shouldn't be a register allocation issue to jump |
| 486 // through a scratch register, so we don't really need to bother | 487 // through a scratch register, so we don't really need to bother |
| 487 // implementing it. | 488 // implementing it. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 if (const auto CallTarget = llvm::dyn_cast<Constant>(getCallTarget())) { | 526 if (const auto CallTarget = llvm::dyn_cast<Constant>(getCallTarget())) { |
| 526 CallTarget->emitWithoutDollar(Func->getContext()); | 527 CallTarget->emitWithoutDollar(Func->getContext()); |
| 527 } else { | 528 } else { |
| 528 Str << "*"; | 529 Str << "*"; |
| 529 getCallTarget()->emit(Func); | 530 getCallTarget()->emit(Func); |
| 530 } | 531 } |
| 531 Func->getTarget()->resetStackAdjustment(); | 532 Func->getTarget()->resetStackAdjustment(); |
| 532 } | 533 } |
| 533 | 534 |
| 534 void InstX8632Call::emitIAS(const Cfg *Func) const { | 535 void InstX8632Call::emitIAS(const Cfg *Func) const { |
| 535 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 536 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 536 Operand *Target = getCallTarget(); | 537 Operand *Target = getCallTarget(); |
| 537 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 538 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { |
| 538 if (Var->hasReg()) { | 539 if (Var->hasReg()) { |
| 539 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum())); | 540 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum())); |
| 540 } else { | 541 } else { |
| 541 Asm->call(static_cast<TargetX8632 *>(Func->getTarget()) | 542 Asm->call(static_cast<TargetX8632 *>(Func->getTarget()) |
| 542 ->stackVarToAsmOperand(Var)); | 543 ->stackVarToAsmOperand(Var)); |
| 543 } | 544 } |
| 544 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { | 545 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { |
| 545 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 546 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 546 Asm->call(Mem->toAsmAddress(Asm)); | 547 Asm->call(Mem->toAsmAddress(Asm)); |
| 547 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { | 548 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { |
| 548 assert(CR->getOffset() == 0 && "We only support calling a function"); | 549 assert(CR->getOffset() == 0 && "We only support calling a function"); |
| 549 Asm->call(CR); | 550 Asm->call(CR); |
| 550 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { | 551 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
| 551 Asm->call(x86::Immediate(Imm->getValue())); | 552 Asm->call(X8632::Immediate(Imm->getValue())); |
| 552 } else { | 553 } else { |
| 553 llvm_unreachable("Unexpected operand type"); | 554 llvm_unreachable("Unexpected operand type"); |
| 554 } | 555 } |
| 555 Func->getTarget()->resetStackAdjustment(); | 556 Func->getTarget()->resetStackAdjustment(); |
| 556 } | 557 } |
| 557 | 558 |
| 558 void InstX8632Call::dump(const Cfg *Func) const { | 559 void InstX8632Call::dump(const Cfg *Func) const { |
| 559 if (!ALLOW_DUMP) | 560 if (!ALLOW_DUMP) |
| 560 return; | 561 return; |
| 561 Ostream &Str = Func->getContext()->getStrDump(); | 562 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 584 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); | 585 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); |
| 585 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) | 586 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) |
| 586 Str << "%cl"; | 587 Str << "%cl"; |
| 587 else | 588 else |
| 588 Src1->emit(Func); | 589 Src1->emit(Func); |
| 589 Str << ", "; | 590 Str << ", "; |
| 590 Dest->emit(Func); | 591 Dest->emit(Func); |
| 591 } | 592 } |
| 592 | 593 |
| 593 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 594 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, |
| 594 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { | 595 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter) { |
| 595 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 596 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 596 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { | 597 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { |
| 597 if (Var->hasReg()) { | 598 if (Var->hasReg()) { |
| 598 // We cheat a little and use GPRRegister even for byte operations. | 599 // We cheat a little and use GPRRegister even for byte operations. |
| 599 RegX8632::GPRRegister VarReg = | 600 RegX8632::GPRRegister VarReg = |
| 600 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); | 601 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| 601 (Asm->*(Emitter.Reg))(Ty, VarReg); | 602 (Asm->*(Emitter.Reg))(Ty, VarReg); |
| 602 } else { | 603 } else { |
| 603 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 604 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 604 ->stackVarToAsmOperand(Var)); | 605 ->stackVarToAsmOperand(Var)); |
| 605 (Asm->*(Emitter.Addr))(Ty, StackAddr); | 606 (Asm->*(Emitter.Addr))(Ty, StackAddr); |
| 606 } | 607 } |
| 607 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { | 608 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { |
| 608 Mem->emitSegmentOverride(Asm); | 609 Mem->emitSegmentOverride(Asm); |
| 609 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); | 610 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); |
| 610 } else { | 611 } else { |
| 611 llvm_unreachable("Unexpected operand type"); | 612 llvm_unreachable("Unexpected operand type"); |
| 612 } | 613 } |
| 613 } | 614 } |
| 614 | 615 |
| 615 template <bool VarCanBeByte, bool SrcCanBeByte> | 616 template <bool VarCanBeByte, bool SrcCanBeByte> |
| 616 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, | 617 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
| 617 const Operand *Src, | 618 const Operand *Src, |
| 618 const x86::AssemblerX86::GPREmitterRegOp &Emitter) { | 619 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter) { |
| 619 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 620 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 620 assert(Var->hasReg()); | 621 assert(Var->hasReg()); |
| 621 // We cheat a little and use GPRRegister even for byte operations. | 622 // We cheat a little and use GPRRegister even for byte operations. |
| 622 RegX8632::GPRRegister VarReg = | 623 RegX8632::GPRRegister VarReg = |
| 623 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()) | 624 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()) |
| 624 : RegX8632::getEncodedGPR(Var->getRegNum()); | 625 : RegX8632::getEncodedGPR(Var->getRegNum()); |
| 625 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 626 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 626 if (SrcVar->hasReg()) { | 627 if (SrcVar->hasReg()) { |
| 627 RegX8632::GPRRegister SrcReg = | 628 RegX8632::GPRRegister SrcReg = |
| 628 SrcCanBeByte | 629 SrcCanBeByte |
| 629 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()) | 630 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()) |
| 630 : RegX8632::getEncodedGPR(SrcVar->getRegNum()); | 631 : RegX8632::getEncodedGPR(SrcVar->getRegNum()); |
| 631 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 632 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 632 } else { | 633 } else { |
| 633 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 634 X8632::Address SrcStackAddr = |
| 634 ->stackVarToAsmOperand(SrcVar); | 635 static_cast<TargetX8632 *>(Func->getTarget()) |
| 636 ->stackVarToAsmOperand(SrcVar); |
| 635 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 637 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
| 636 } | 638 } |
| 637 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 639 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 638 Mem->emitSegmentOverride(Asm); | 640 Mem->emitSegmentOverride(Asm); |
| 639 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 641 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 640 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 642 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 641 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 643 (Asm->*(Emitter.GPRImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); |
| 642 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 644 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 643 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); | 645 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); |
| 644 (Asm->*(Emitter.GPRImm))(Ty, VarReg, | 646 (Asm->*(Emitter.GPRImm))(Ty, VarReg, |
| 645 x86::Immediate(Reloc->getOffset(), Fixup)); | 647 X8632::Immediate(Reloc->getOffset(), Fixup)); |
| 646 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { | 648 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { |
| 647 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 649 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
| 648 } else { | 650 } else { |
| 649 llvm_unreachable("Unexpected operand type"); | 651 llvm_unreachable("Unexpected operand type"); |
| 650 } | 652 } |
| 651 } | 653 } |
| 652 | 654 |
| 653 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, | 655 void emitIASAddrOpTyGPR( |
| 654 const Operand *Src, | 656 const Cfg *Func, Type Ty, const X8632::Address &Addr, const Operand *Src, |
| 655 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { | 657 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) { |
| 656 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 658 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 657 // Src can only be Reg or Immediate. | 659 // Src can only be Reg or Immediate. |
| 658 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 660 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 659 assert(SrcVar->hasReg()); | 661 assert(SrcVar->hasReg()); |
| 660 RegX8632::GPRRegister SrcReg = | 662 RegX8632::GPRRegister SrcReg = |
| 661 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 663 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 662 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 664 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 663 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 665 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 664 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); | 666 (Asm->*(Emitter.AddrImm))(Ty, Addr, X8632::Immediate(Imm->getValue())); |
| 665 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 667 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 666 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); | 668 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); |
| 667 (Asm->*(Emitter.AddrImm))(Ty, Addr, | 669 (Asm->*(Emitter.AddrImm))(Ty, Addr, |
| 668 x86::Immediate(Reloc->getOffset(), Fixup)); | 670 X8632::Immediate(Reloc->getOffset(), Fixup)); |
| 669 } else { | 671 } else { |
| 670 llvm_unreachable("Unexpected operand type"); | 672 llvm_unreachable("Unexpected operand type"); |
| 671 } | 673 } |
| 672 } | 674 } |
| 673 | 675 |
| 674 void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0, | 676 void emitIASAsAddrOpTyGPR( |
| 675 const Operand *Op1, | 677 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
| 676 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { | 678 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) { |
| 677 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) { | 679 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) { |
| 678 assert(!Op0Var->hasReg()); | 680 assert(!Op0Var->hasReg()); |
| 679 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 681 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 680 ->stackVarToAsmOperand(Op0Var)); | 682 ->stackVarToAsmOperand(Op0Var)); |
| 681 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter); | 683 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter); |
| 682 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) { | 684 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) { |
| 683 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 685 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 684 Op0Mem->emitSegmentOverride(Asm); | 686 Op0Mem->emitSegmentOverride(Asm); |
| 685 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter); | 687 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter); |
| 686 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) { | 688 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) { |
| 687 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter); | 689 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter); |
| 688 } else { | 690 } else { |
| 689 llvm_unreachable("Unexpected operand type"); | 691 llvm_unreachable("Unexpected operand type"); |
| 690 } | 692 } |
| 691 } | 693 } |
| 692 | 694 |
| 693 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, | 695 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 694 const Operand *Src, | 696 const Operand *Src, |
| 695 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { | 697 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter) { |
| 696 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 698 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 697 // Technically, the Dest Var can be mem as well, but we only use Reg. | 699 // Technically, the Dest Var can be mem as well, but we only use Reg. |
| 698 // We can extend this to check Dest if we decide to use that form. | 700 // We can extend this to check Dest if we decide to use that form. |
| 699 assert(Var->hasReg()); | 701 assert(Var->hasReg()); |
| 700 // We cheat a little and use GPRRegister even for byte operations. | 702 // We cheat a little and use GPRRegister even for byte operations. |
| 701 RegX8632::GPRRegister VarReg = | 703 RegX8632::GPRRegister VarReg = |
| 702 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); | 704 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| 703 // Src must be reg == ECX or an Imm8. | 705 // Src must be reg == ECX or an Imm8. |
| 704 // This is asserted by the assembler. | 706 // This is asserted by the assembler. |
| 705 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 707 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 706 assert(SrcVar->hasReg()); | 708 assert(SrcVar->hasReg()); |
| 707 RegX8632::GPRRegister SrcReg = | 709 RegX8632::GPRRegister SrcReg = |
| 708 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 710 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 709 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 711 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 710 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 712 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 711 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 713 (Asm->*(Emitter.GPRImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); |
| 712 } else { | 714 } else { |
| 713 llvm_unreachable("Unexpected operand type"); | 715 llvm_unreachable("Unexpected operand type"); |
| 714 } | 716 } |
| 715 } | 717 } |
| 716 | 718 |
| 717 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, | 719 void emitIASGPRShiftDouble( |
| 718 const Operand *Src1Op, const Operand *Src2Op, | 720 const Cfg *Func, const Variable *Dest, const Operand *Src1Op, |
| 719 const x86::AssemblerX86::GPREmitterShiftD &Emitter) { | 721 const Operand *Src2Op, |
| 720 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 722 const X8632::AssemblerX8632::GPREmitterShiftD &Emitter) { |
| 723 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 721 // Dest can be reg or mem, but we only use the reg variant. | 724 // Dest can be reg or mem, but we only use the reg variant. |
| 722 assert(Dest->hasReg()); | 725 assert(Dest->hasReg()); |
| 723 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); | 726 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); |
| 724 // SrcVar1 must be reg. | 727 // SrcVar1 must be reg. |
| 725 const auto SrcVar1 = llvm::cast<Variable>(Src1Op); | 728 const auto SrcVar1 = llvm::cast<Variable>(Src1Op); |
| 726 assert(SrcVar1->hasReg()); | 729 assert(SrcVar1->hasReg()); |
| 727 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum()); | 730 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum()); |
| 728 Type Ty = SrcVar1->getType(); | 731 Type Ty = SrcVar1->getType(); |
| 729 // Src2 can be the implicit CL register or an immediate. | 732 // Src2 can be the implicit CL register or an immediate. |
| 730 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { | 733 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { |
| 731 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, | 734 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, |
| 732 x86::Immediate(Imm->getValue())); | 735 X8632::Immediate(Imm->getValue())); |
| 733 } else { | 736 } else { |
| 734 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); | 737 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); |
| 735 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); | 738 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); |
| 736 } | 739 } |
| 737 } | 740 } |
| 738 | 741 |
| 739 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, | 742 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 740 const Operand *Src, | 743 const Operand *Src, |
| 741 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { | 744 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter) { |
| 742 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 745 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 743 assert(Var->hasReg()); | 746 assert(Var->hasReg()); |
| 744 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 747 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 745 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 748 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 746 if (SrcVar->hasReg()) { | 749 if (SrcVar->hasReg()) { |
| 747 RegX8632::XmmRegister SrcReg = | 750 RegX8632::XmmRegister SrcReg = |
| 748 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 751 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 749 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 752 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 750 } else { | 753 } else { |
| 751 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 754 X8632::Address SrcStackAddr = |
| 752 ->stackVarToAsmOperand(SrcVar); | 755 static_cast<TargetX8632 *>(Func->getTarget()) |
| 756 ->stackVarToAsmOperand(SrcVar); |
| 753 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 757 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 754 } | 758 } |
| 755 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 759 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 756 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 760 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 757 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 761 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 758 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 762 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 759 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 763 (Asm->*(Emitter.XmmImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); |
| 760 } else { | 764 } else { |
| 761 llvm_unreachable("Unexpected operand type"); | 765 llvm_unreachable("Unexpected operand type"); |
| 762 } | 766 } |
| 763 } | 767 } |
| 764 | 768 |
| 765 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 769 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
| 766 const Operand *Src, | 770 const Operand *Src, |
| 767 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { | 771 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { |
| 768 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 772 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 769 assert(Var->hasReg()); | 773 assert(Var->hasReg()); |
| 770 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 774 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 771 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 775 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 772 if (SrcVar->hasReg()) { | 776 if (SrcVar->hasReg()) { |
| 773 RegX8632::XmmRegister SrcReg = | 777 RegX8632::XmmRegister SrcReg = |
| 774 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 778 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 775 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 779 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 776 } else { | 780 } else { |
| 777 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 781 X8632::Address SrcStackAddr = |
| 778 ->stackVarToAsmOperand(SrcVar); | 782 static_cast<TargetX8632 *>(Func->getTarget()) |
| 783 ->stackVarToAsmOperand(SrcVar); |
| 779 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 784 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 780 } | 785 } |
| 781 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 786 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 782 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 787 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 783 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 788 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 784 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 789 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
| 785 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, x86::Address::ofConstPool(Asm, Imm)); | 790 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, |
| 791 X8632::Address::ofConstPool(Asm, Imm)); |
| 786 } else { | 792 } else { |
| 787 llvm_unreachable("Unexpected operand type"); | 793 llvm_unreachable("Unexpected operand type"); |
| 788 } | 794 } |
| 789 } | 795 } |
| 790 | 796 |
| 791 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | 797 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), |
| 792 SReg_t (*srcEnc)(int32_t)> | 798 SReg_t (*srcEnc)(int32_t)> |
| 793 void emitIASCastRegOp( | 799 void emitIASCastRegOp( |
| 794 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, | 800 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, |
| 795 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { | 801 const X8632::AssemblerX8632::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { |
| 796 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 802 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 797 assert(Dest->hasReg()); | 803 assert(Dest->hasReg()); |
| 798 DReg_t DestReg = destEnc(Dest->getRegNum()); | 804 DReg_t DestReg = destEnc(Dest->getRegNum()); |
| 799 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 805 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 800 if (SrcVar->hasReg()) { | 806 if (SrcVar->hasReg()) { |
| 801 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 807 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| 802 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); | 808 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); |
| 803 } else { | 809 } else { |
| 804 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 810 X8632::Address SrcStackAddr = |
| 805 ->stackVarToAsmOperand(SrcVar); | 811 static_cast<TargetX8632 *>(Func->getTarget()) |
| 812 ->stackVarToAsmOperand(SrcVar); |
| 806 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); | 813 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); |
| 807 } | 814 } |
| 808 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 815 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 809 Mem->emitSegmentOverride(Asm); | 816 Mem->emitSegmentOverride(Asm); |
| 810 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); | 817 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); |
| 811 } else { | 818 } else { |
| 812 llvm_unreachable("Unexpected operand type"); | 819 llvm_unreachable("Unexpected operand type"); |
| 813 } | 820 } |
| 814 } | 821 } |
| 815 | 822 |
| 816 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | 823 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), |
| 817 SReg_t (*srcEnc)(int32_t)> | 824 SReg_t (*srcEnc)(int32_t)> |
| 818 void emitIASThreeOpImmOps( | 825 void emitIASThreeOpImmOps( |
| 819 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, | 826 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, |
| 820 const Operand *Src1, | 827 const Operand *Src1, |
| 821 const x86::AssemblerX86::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { | 828 const X8632::AssemblerX8632::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { |
| 822 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 829 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 823 // This only handles Dest being a register, and Src1 being an immediate. | 830 // This only handles Dest being a register, and Src1 being an immediate. |
| 824 assert(Dest->hasReg()); | 831 assert(Dest->hasReg()); |
| 825 DReg_t DestReg = destEnc(Dest->getRegNum()); | 832 DReg_t DestReg = destEnc(Dest->getRegNum()); |
| 826 x86::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); | 833 X8632::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); |
| 827 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { | 834 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { |
| 828 if (SrcVar->hasReg()) { | 835 if (SrcVar->hasReg()) { |
| 829 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 836 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| 830 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); | 837 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); |
| 831 } else { | 838 } else { |
| 832 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 839 X8632::Address SrcStackAddr = |
| 833 ->stackVarToAsmOperand(SrcVar); | 840 static_cast<TargetX8632 *>(Func->getTarget()) |
| 841 ->stackVarToAsmOperand(SrcVar); |
| 834 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); | 842 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); |
| 835 } | 843 } |
| 836 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 844 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 837 Mem->emitSegmentOverride(Asm); | 845 Mem->emitSegmentOverride(Asm); |
| 838 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), | 846 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), |
| 839 Imm); | 847 Imm); |
| 840 } else { | 848 } else { |
| 841 llvm_unreachable("Unexpected operand type"); | 849 llvm_unreachable("Unexpected operand type"); |
| 842 } | 850 } |
| 843 } | 851 } |
| 844 | 852 |
| 845 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, | 853 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
| 846 const Operand *Src, | 854 const Operand *Src, |
| 847 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { | 855 const X8632::AssemblerX8632::XmmEmitterMovOps Emitter) { |
| 848 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 856 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 849 if (Dest->hasReg()) { | 857 if (Dest->hasReg()) { |
| 850 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 858 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 851 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 859 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 852 if (SrcVar->hasReg()) { | 860 if (SrcVar->hasReg()) { |
| 853 (Asm->*(Emitter.XmmXmm))(DestReg, | 861 (Asm->*(Emitter.XmmXmm))(DestReg, |
| 854 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 862 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 855 } else { | 863 } else { |
| 856 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 864 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 857 ->stackVarToAsmOperand(SrcVar)); | 865 ->stackVarToAsmOperand(SrcVar)); |
| 858 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); | 866 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); |
| 859 } | 867 } |
| 860 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 868 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 861 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 869 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 862 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); | 870 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
| 863 } else { | 871 } else { |
| 864 llvm_unreachable("Unexpected operand type"); | 872 llvm_unreachable("Unexpected operand type"); |
| 865 } | 873 } |
| 866 } else { | 874 } else { |
| 867 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 875 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 868 ->stackVarToAsmOperand(Dest)); | 876 ->stackVarToAsmOperand(Dest)); |
| 869 // Src must be a register in this case. | 877 // Src must be a register in this case. |
| 870 const auto SrcVar = llvm::cast<Variable>(Src); | 878 const auto SrcVar = llvm::cast<Variable>(Src); |
| 871 assert(SrcVar->hasReg()); | 879 assert(SrcVar->hasReg()); |
| 872 (Asm->*(Emitter.AddrXmm))(StackAddr, | 880 (Asm->*(Emitter.AddrXmm))(StackAddr, |
| 873 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 881 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 874 } | 882 } |
| 875 } | 883 } |
| 876 | 884 |
| 877 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { | 885 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
| 878 const auto SrcVar = llvm::dyn_cast<const Variable>(Source); | 886 const auto SrcVar = llvm::dyn_cast<const Variable>(Source); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 template <> const char *InstX8632Shufps::Opcode = "shufps"; | 956 template <> const char *InstX8632Shufps::Opcode = "shufps"; |
| 949 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; | 957 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; |
| 950 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; | 958 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; |
| 951 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; | 959 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; |
| 952 // Three address ops | 960 // Three address ops |
| 953 template <> const char *InstX8632Pextr::Opcode = "pextr"; | 961 template <> const char *InstX8632Pextr::Opcode = "pextr"; |
| 954 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; | 962 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; |
| 955 | 963 |
| 956 // Inplace GPR ops | 964 // Inplace GPR ops |
| 957 template <> | 965 template <> |
| 958 const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = { | 966 const X8632::AssemblerX8632::GPREmitterOneOp InstX8632Bswap::Emitter = { |
| 959 &x86::AssemblerX86::bswap, nullptr /* only a reg form exists */ | 967 &X8632::AssemblerX8632::bswap, nullptr /* only a reg form exists */ |
| 960 }; | 968 }; |
| 961 template <> | 969 template <> |
| 962 const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = { | 970 const X8632::AssemblerX8632::GPREmitterOneOp InstX8632Neg::Emitter = { |
| 963 &x86::AssemblerX86::neg, &x86::AssemblerX86::neg}; | 971 &X8632::AssemblerX8632::neg, &X8632::AssemblerX8632::neg}; |
| 964 | 972 |
| 965 // Unary GPR ops | 973 // Unary GPR ops |
| 966 template <> | 974 template <> |
| 967 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = { | 975 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Bsf::Emitter = { |
| 968 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, nullptr}; | 976 &X8632::AssemblerX8632::bsf, &X8632::AssemblerX8632::bsf, nullptr}; |
| 969 template <> | 977 template <> |
| 970 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { | 978 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Bsr::Emitter = { |
| 971 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, nullptr}; | 979 &X8632::AssemblerX8632::bsr, &X8632::AssemblerX8632::bsr, nullptr}; |
| 972 template <> | 980 template <> |
| 973 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { | 981 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Lea::Emitter = { |
| 974 /* reg/reg and reg/imm are illegal */ nullptr, &x86::AssemblerX86::lea, | 982 /* reg/reg and reg/imm are illegal */ nullptr, &X8632::AssemblerX8632::lea, |
| 975 nullptr}; | 983 nullptr}; |
| 976 template <> | 984 template <> |
| 977 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = { | 985 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Movsx::Emitter = { |
| 978 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, nullptr}; | 986 &X8632::AssemblerX8632::movsx, &X8632::AssemblerX8632::movsx, nullptr}; |
| 979 template <> | 987 template <> |
| 980 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = { | 988 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Movzx::Emitter = { |
| 981 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, nullptr}; | 989 &X8632::AssemblerX8632::movzx, &X8632::AssemblerX8632::movzx, nullptr}; |
| 982 | 990 |
| 983 // Unary XMM ops | 991 // Unary XMM ops |
| 984 template <> | 992 template <> |
| 985 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { | 993 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { |
| 986 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss}; | 994 &X8632::AssemblerX8632::sqrtss, &X8632::AssemblerX8632::sqrtss}; |
| 987 | 995 |
| 988 // Binary GPR ops | 996 // Binary GPR ops |
| 989 template <> | 997 template <> |
| 990 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { | 998 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Add::Emitter = { |
| 991 &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add}; | 999 &X8632::AssemblerX8632::add, &X8632::AssemblerX8632::add, |
| 1000 &X8632::AssemblerX8632::add}; |
| 992 template <> | 1001 template <> |
| 993 const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = { | 1002 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Adc::Emitter = { |
| 994 &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc}; | 1003 &X8632::AssemblerX8632::adc, &X8632::AssemblerX8632::adc, |
| 1004 &X8632::AssemblerX8632::adc}; |
| 995 template <> | 1005 template <> |
| 996 const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = { | 1006 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632And::Emitter = { |
| 997 &x86::AssemblerX86::And, &x86::AssemblerX86::And, &x86::AssemblerX86::And}; | 1007 &X8632::AssemblerX8632::And, &X8632::AssemblerX8632::And, |
| 1008 &X8632::AssemblerX8632::And}; |
| 998 template <> | 1009 template <> |
| 999 const x86::AssemblerX86::GPREmitterRegOp InstX8632Or::Emitter = { | 1010 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Or::Emitter = { |
| 1000 &x86::AssemblerX86::Or, &x86::AssemblerX86::Or, &x86::AssemblerX86::Or}; | 1011 &X8632::AssemblerX8632::Or, &X8632::AssemblerX8632::Or, |
| 1012 &X8632::AssemblerX8632::Or}; |
| 1001 template <> | 1013 template <> |
| 1002 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sbb::Emitter = { | 1014 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Sbb::Emitter = { |
| 1003 &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb}; | 1015 &X8632::AssemblerX8632::sbb, &X8632::AssemblerX8632::sbb, |
| 1016 &X8632::AssemblerX8632::sbb}; |
| 1004 template <> | 1017 template <> |
| 1005 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sub::Emitter = { | 1018 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Sub::Emitter = { |
| 1006 &x86::AssemblerX86::sub, &x86::AssemblerX86::sub, &x86::AssemblerX86::sub}; | 1019 &X8632::AssemblerX8632::sub, &X8632::AssemblerX8632::sub, |
| 1020 &X8632::AssemblerX8632::sub}; |
| 1007 template <> | 1021 template <> |
| 1008 const x86::AssemblerX86::GPREmitterRegOp InstX8632Xor::Emitter = { | 1022 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Xor::Emitter = { |
| 1009 &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor}; | 1023 &X8632::AssemblerX8632::Xor, &X8632::AssemblerX8632::Xor, |
| 1024 &X8632::AssemblerX8632::Xor}; |
| 1010 | 1025 |
| 1011 // Binary Shift GPR ops | 1026 // Binary Shift GPR ops |
| 1012 template <> | 1027 template <> |
| 1013 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Rol::Emitter = { | 1028 const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Rol::Emitter = { |
| 1014 &x86::AssemblerX86::rol, &x86::AssemblerX86::rol}; | 1029 &X8632::AssemblerX8632::rol, &X8632::AssemblerX8632::rol}; |
| 1015 template <> | 1030 template <> |
| 1016 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Sar::Emitter = { | 1031 const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Sar::Emitter = { |
| 1017 &x86::AssemblerX86::sar, &x86::AssemblerX86::sar}; | 1032 &X8632::AssemblerX8632::sar, &X8632::AssemblerX8632::sar}; |
| 1018 template <> | 1033 template <> |
| 1019 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = { | 1034 const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Shl::Emitter = { |
| 1020 &x86::AssemblerX86::shl, &x86::AssemblerX86::shl}; | 1035 &X8632::AssemblerX8632::shl, &X8632::AssemblerX8632::shl}; |
| 1021 template <> | 1036 template <> |
| 1022 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = { | 1037 const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Shr::Emitter = { |
| 1023 &x86::AssemblerX86::shr, &x86::AssemblerX86::shr}; | 1038 &X8632::AssemblerX8632::shr, &X8632::AssemblerX8632::shr}; |
| 1024 | 1039 |
| 1025 // Binary XMM ops | 1040 // Binary XMM ops |
| 1026 template <> | 1041 template <> |
| 1027 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addss::Emitter = { | 1042 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Addss::Emitter = { |
| 1028 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss}; | 1043 &X8632::AssemblerX8632::addss, &X8632::AssemblerX8632::addss}; |
| 1029 template <> | 1044 template <> |
| 1030 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addps::Emitter = { | 1045 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Addps::Emitter = { |
| 1031 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps}; | 1046 &X8632::AssemblerX8632::addps, &X8632::AssemblerX8632::addps}; |
| 1032 template <> | 1047 template <> |
| 1033 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divss::Emitter = { | 1048 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Divss::Emitter = { |
| 1034 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss}; | 1049 &X8632::AssemblerX8632::divss, &X8632::AssemblerX8632::divss}; |
| 1035 template <> | 1050 template <> |
| 1036 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divps::Emitter = { | 1051 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Divps::Emitter = { |
| 1037 &x86::AssemblerX86::divps, &x86::AssemblerX86::divps}; | 1052 &X8632::AssemblerX8632::divps, &X8632::AssemblerX8632::divps}; |
| 1038 template <> | 1053 template <> |
| 1039 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulss::Emitter = { | 1054 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Mulss::Emitter = { |
| 1040 &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss}; | 1055 &X8632::AssemblerX8632::mulss, &X8632::AssemblerX8632::mulss}; |
| 1041 template <> | 1056 template <> |
| 1042 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulps::Emitter = { | 1057 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Mulps::Emitter = { |
| 1043 &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps}; | 1058 &X8632::AssemblerX8632::mulps, &X8632::AssemblerX8632::mulps}; |
| 1044 template <> | 1059 template <> |
| 1045 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Padd::Emitter = { | 1060 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Padd::Emitter = { |
| 1046 &x86::AssemblerX86::padd, &x86::AssemblerX86::padd}; | 1061 &X8632::AssemblerX8632::padd, &X8632::AssemblerX8632::padd}; |
| 1047 template <> | 1062 template <> |
| 1048 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pand::Emitter = { | 1063 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pand::Emitter = { |
| 1049 &x86::AssemblerX86::pand, &x86::AssemblerX86::pand}; | 1064 &X8632::AssemblerX8632::pand, &X8632::AssemblerX8632::pand}; |
| 1050 template <> | 1065 template <> |
| 1051 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pandn::Emitter = { | 1066 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pandn::Emitter = { |
| 1052 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn}; | 1067 &X8632::AssemblerX8632::pandn, &X8632::AssemblerX8632::pandn}; |
| 1053 template <> | 1068 template <> |
| 1054 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = { | 1069 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = { |
| 1055 &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq}; | 1070 &X8632::AssemblerX8632::pcmpeq, &X8632::AssemblerX8632::pcmpeq}; |
| 1056 template <> | 1071 template <> |
| 1057 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = { | 1072 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = { |
| 1058 &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt}; | 1073 &X8632::AssemblerX8632::pcmpgt, &X8632::AssemblerX8632::pcmpgt}; |
| 1059 template <> | 1074 template <> |
| 1060 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmull::Emitter = { | 1075 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pmull::Emitter = { |
| 1061 &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull}; | 1076 &X8632::AssemblerX8632::pmull, &X8632::AssemblerX8632::pmull}; |
| 1062 template <> | 1077 template <> |
| 1063 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmuludq::Emitter = { | 1078 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pmuludq::Emitter = { |
| 1064 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq}; | 1079 &X8632::AssemblerX8632::pmuludq, &X8632::AssemblerX8632::pmuludq}; |
| 1065 template <> | 1080 template <> |
| 1066 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Por::Emitter = { | 1081 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Por::Emitter = { |
| 1067 &x86::AssemblerX86::por, &x86::AssemblerX86::por}; | 1082 &X8632::AssemblerX8632::por, &X8632::AssemblerX8632::por}; |
| 1068 template <> | 1083 template <> |
| 1069 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Psub::Emitter = { | 1084 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Psub::Emitter = { |
| 1070 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub}; | 1085 &X8632::AssemblerX8632::psub, &X8632::AssemblerX8632::psub}; |
| 1071 template <> | 1086 template <> |
| 1072 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pxor::Emitter = { | 1087 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pxor::Emitter = { |
| 1073 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor}; | 1088 &X8632::AssemblerX8632::pxor, &X8632::AssemblerX8632::pxor}; |
| 1074 template <> | 1089 template <> |
| 1075 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subss::Emitter = { | 1090 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Subss::Emitter = { |
| 1076 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss}; | 1091 &X8632::AssemblerX8632::subss, &X8632::AssemblerX8632::subss}; |
| 1077 template <> | 1092 template <> |
| 1078 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subps::Emitter = { | 1093 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Subps::Emitter = { |
| 1079 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps}; | 1094 &X8632::AssemblerX8632::subps, &X8632::AssemblerX8632::subps}; |
| 1080 | 1095 |
| 1081 // Binary XMM Shift ops | 1096 // Binary XMM Shift ops |
| 1082 template <> | 1097 template <> |
| 1083 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = { | 1098 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psll::Emitter = { |
| 1084 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll, | 1099 &X8632::AssemblerX8632::psll, &X8632::AssemblerX8632::psll, |
| 1085 &x86::AssemblerX86::psll}; | 1100 &X8632::AssemblerX8632::psll}; |
| 1086 template <> | 1101 template <> |
| 1087 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { | 1102 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psra::Emitter = { |
| 1088 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, | 1103 &X8632::AssemblerX8632::psra, &X8632::AssemblerX8632::psra, |
| 1089 &x86::AssemblerX86::psra}; | 1104 &X8632::AssemblerX8632::psra}; |
| 1090 template <> | 1105 template <> |
| 1091 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psrl::Emitter = { | 1106 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psrl::Emitter = { |
| 1092 &x86::AssemblerX86::psrl, &x86::AssemblerX86::psrl, | 1107 &X8632::AssemblerX8632::psrl, &X8632::AssemblerX8632::psrl, |
| 1093 &x86::AssemblerX86::psrl}; | 1108 &X8632::AssemblerX8632::psrl}; |
| 1094 | 1109 |
| 1095 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 1110 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { |
| 1096 if (!ALLOW_DUMP) | 1111 if (!ALLOW_DUMP) |
| 1097 return; | 1112 return; |
| 1098 Ostream &Str = Func->getContext()->getStrEmit(); | 1113 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1099 assert(getSrcSize() == 1); | 1114 assert(getSrcSize() == 1); |
| 1100 Type Ty = getSrc(0)->getType(); | 1115 Type Ty = getSrc(0)->getType(); |
| 1101 assert(isScalarFloatingType(Ty)); | 1116 assert(isScalarFloatingType(Ty)); |
| 1102 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 1117 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
| 1103 getSrc(0)->emit(Func); | 1118 getSrc(0)->emit(Func); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 assert(getSrcSize() == 3); | 1224 assert(getSrcSize() == 3); |
| 1210 Operand *Src1 = getSrc(1); | 1225 Operand *Src1 = getSrc(1); |
| 1211 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; | 1226 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; |
| 1212 Src1->emit(Func); | 1227 Src1->emit(Func); |
| 1213 } | 1228 } |
| 1214 | 1229 |
| 1215 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { | 1230 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { |
| 1216 assert(getSrcSize() == 3); | 1231 assert(getSrcSize() == 3); |
| 1217 const Operand *Src = getSrc(1); | 1232 const Operand *Src = getSrc(1); |
| 1218 Type Ty = Src->getType(); | 1233 Type Ty = Src->getType(); |
| 1219 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1234 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
| 1220 &x86::AssemblerX86::div, &x86::AssemblerX86::div}; | 1235 &X8632::AssemblerX8632::div, &X8632::AssemblerX8632::div}; |
| 1221 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1236 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| 1222 } | 1237 } |
| 1223 | 1238 |
| 1224 template <> void InstX8632Idiv::emit(const Cfg *Func) const { | 1239 template <> void InstX8632Idiv::emit(const Cfg *Func) const { |
| 1225 if (!ALLOW_DUMP) | 1240 if (!ALLOW_DUMP) |
| 1226 return; | 1241 return; |
| 1227 Ostream &Str = Func->getContext()->getStrEmit(); | 1242 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1228 assert(getSrcSize() == 3); | 1243 assert(getSrcSize() == 3); |
| 1229 Operand *Src1 = getSrc(1); | 1244 Operand *Src1 = getSrc(1); |
| 1230 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; | 1245 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; |
| 1231 Src1->emit(Func); | 1246 Src1->emit(Func); |
| 1232 } | 1247 } |
| 1233 | 1248 |
| 1234 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { | 1249 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { |
| 1235 assert(getSrcSize() == 3); | 1250 assert(getSrcSize() == 3); |
| 1236 const Operand *Src = getSrc(1); | 1251 const Operand *Src = getSrc(1); |
| 1237 Type Ty = Src->getType(); | 1252 Type Ty = Src->getType(); |
| 1238 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1253 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
| 1239 &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv}; | 1254 &X8632::AssemblerX8632::idiv, &X8632::AssemblerX8632::idiv}; |
| 1240 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1255 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| 1241 } | 1256 } |
| 1242 | 1257 |
| 1243 namespace { | 1258 namespace { |
| 1244 | 1259 |
| 1245 // pblendvb and blendvps take xmm0 as a final implicit argument. | 1260 // pblendvb and blendvps take xmm0 as a final implicit argument. |
| 1246 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, | 1261 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, |
| 1247 const Cfg *Func) { | 1262 const Cfg *Func) { |
| 1248 if (!ALLOW_DUMP) | 1263 if (!ALLOW_DUMP) |
| 1249 return; | 1264 return; |
| 1250 Ostream &Str = Func->getContext()->getStrEmit(); | 1265 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1251 assert(Inst->getSrcSize() == 3); | 1266 assert(Inst->getSrcSize() == 3); |
| 1252 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1267 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
| 1253 RegX8632::Reg_xmm0); | 1268 RegX8632::Reg_xmm0); |
| 1254 Str << "\t" << Opcode << "\t"; | 1269 Str << "\t" << Opcode << "\t"; |
| 1255 Inst->getSrc(1)->emit(Func); | 1270 Inst->getSrc(1)->emit(Func); |
| 1256 Str << ", "; | 1271 Str << ", "; |
| 1257 Inst->getDest()->emit(Func); | 1272 Inst->getDest()->emit(Func); |
| 1258 } | 1273 } |
| 1259 | 1274 |
| 1260 void emitIASVariableBlendInst( | 1275 void emitIASVariableBlendInst( |
| 1261 const Inst *Inst, const Cfg *Func, | 1276 const Inst *Inst, const Cfg *Func, |
| 1262 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { | 1277 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { |
| 1263 assert(Inst->getSrcSize() == 3); | 1278 assert(Inst->getSrcSize() == 3); |
| 1264 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1279 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
| 1265 RegX8632::Reg_xmm0); | 1280 RegX8632::Reg_xmm0); |
| 1266 const Variable *Dest = Inst->getDest(); | 1281 const Variable *Dest = Inst->getDest(); |
| 1267 const Operand *Src = Inst->getSrc(1); | 1282 const Operand *Src = Inst->getSrc(1); |
| 1268 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); | 1283 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); |
| 1269 } | 1284 } |
| 1270 | 1285 |
| 1271 } // end anonymous namespace | 1286 } // end anonymous namespace |
| 1272 | 1287 |
| 1273 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { | 1288 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { |
| 1274 if (!ALLOW_DUMP) | 1289 if (!ALLOW_DUMP) |
| 1275 return; | 1290 return; |
| 1276 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1291 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1277 TargetX8632::SSE4_1); | 1292 TargetX8632::SSE4_1); |
| 1278 emitVariableBlendInst(Opcode, this, Func); | 1293 emitVariableBlendInst(Opcode, this, Func); |
| 1279 } | 1294 } |
| 1280 | 1295 |
| 1281 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { | 1296 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { |
| 1282 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1297 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1283 TargetX8632::SSE4_1); | 1298 TargetX8632::SSE4_1); |
| 1284 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1299 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1285 &x86::AssemblerX86::blendvps, &x86::AssemblerX86::blendvps}; | 1300 &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps}; |
| 1286 emitIASVariableBlendInst(this, Func, Emitter); | 1301 emitIASVariableBlendInst(this, Func, Emitter); |
| 1287 } | 1302 } |
| 1288 | 1303 |
| 1289 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { | 1304 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { |
| 1290 if (!ALLOW_DUMP) | 1305 if (!ALLOW_DUMP) |
| 1291 return; | 1306 return; |
| 1292 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1307 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1293 TargetX8632::SSE4_1); | 1308 TargetX8632::SSE4_1); |
| 1294 emitVariableBlendInst(Opcode, this, Func); | 1309 emitVariableBlendInst(Opcode, this, Func); |
| 1295 } | 1310 } |
| 1296 | 1311 |
| 1297 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { | 1312 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { |
| 1298 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1313 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1299 TargetX8632::SSE4_1); | 1314 TargetX8632::SSE4_1); |
| 1300 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1315 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1301 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb}; | 1316 &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb}; |
| 1302 emitIASVariableBlendInst(this, Func, Emitter); | 1317 emitIASVariableBlendInst(this, Func, Emitter); |
| 1303 } | 1318 } |
| 1304 | 1319 |
| 1305 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 1320 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
| 1306 if (!ALLOW_DUMP) | 1321 if (!ALLOW_DUMP) |
| 1307 return; | 1322 return; |
| 1308 Ostream &Str = Func->getContext()->getStrEmit(); | 1323 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1309 assert(getSrcSize() == 2); | 1324 assert(getSrcSize() == 2); |
| 1310 Variable *Dest = getDest(); | 1325 Variable *Dest = getDest(); |
| 1311 if (isByteSizedArithType(Dest->getType())) { | 1326 if (isByteSizedArithType(Dest->getType())) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1330 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { | 1345 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { |
| 1331 assert(getSrcSize() == 2); | 1346 assert(getSrcSize() == 2); |
| 1332 const Variable *Var = getDest(); | 1347 const Variable *Var = getDest(); |
| 1333 Type Ty = Var->getType(); | 1348 Type Ty = Var->getType(); |
| 1334 const Operand *Src = getSrc(1); | 1349 const Operand *Src = getSrc(1); |
| 1335 if (isByteSizedArithType(Ty)) { | 1350 if (isByteSizedArithType(Ty)) { |
| 1336 // The 8-bit version of imul only allows the form "imul r/m8". | 1351 // The 8-bit version of imul only allows the form "imul r/m8". |
| 1337 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); | 1352 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); |
| 1338 (void)Src0Var; | 1353 (void)Src0Var; |
| 1339 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); | 1354 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); |
| 1340 const x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1355 const X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
| 1341 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul}; | 1356 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul}; |
| 1342 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); | 1357 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); |
| 1343 } else { | 1358 } else { |
| 1344 // We only use imul as a two-address instruction even though | 1359 // We only use imul as a two-address instruction even though |
| 1345 // there is a 3 operand version when one of the operands is a constant. | 1360 // there is a 3 operand version when one of the operands is a constant. |
| 1346 assert(Var == getSrc(0)); | 1361 assert(Var == getSrc(0)); |
| 1347 const x86::AssemblerX86::GPREmitterRegOp Emitter = { | 1362 const X8632::AssemblerX8632::GPREmitterRegOp Emitter = { |
| 1348 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul, | 1363 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul, |
| 1349 &x86::AssemblerX86::imul}; | 1364 &X8632::AssemblerX8632::imul}; |
| 1350 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); | 1365 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); |
| 1351 } | 1366 } |
| 1352 } | 1367 } |
| 1353 | 1368 |
| 1354 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { | 1369 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { |
| 1355 assert(getSrcSize() == 3); | 1370 assert(getSrcSize() == 3); |
| 1356 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1371 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1357 TargetX8632::SSE4_1); | 1372 TargetX8632::SSE4_1); |
| 1358 const Variable *Dest = getDest(); | 1373 const Variable *Dest = getDest(); |
| 1359 assert(Dest == getSrc(0)); | 1374 assert(Dest == getSrc(0)); |
| 1360 Type Ty = Dest->getType(); | 1375 Type Ty = Dest->getType(); |
| 1361 static const x86::AssemblerX86::ThreeOpImmEmitter< | 1376 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 1362 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 1377 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
| 1363 &x86::AssemblerX86::insertps, &x86::AssemblerX86::insertps}; | 1378 &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps}; |
| 1364 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 1379 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
| 1365 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 1380 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
| 1366 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 1381 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
| 1367 } | 1382 } |
| 1368 | 1383 |
| 1369 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { | 1384 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { |
| 1370 if (!ALLOW_DUMP) | 1385 if (!ALLOW_DUMP) |
| 1371 return; | 1386 return; |
| 1372 Ostream &Str = Func->getContext()->getStrEmit(); | 1387 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1373 assert(getSrcSize() == 1); | 1388 assert(getSrcSize() == 1); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1387 Str << "\tcwtd"; | 1402 Str << "\tcwtd"; |
| 1388 break; | 1403 break; |
| 1389 case IceType_i32: | 1404 case IceType_i32: |
| 1390 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1405 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 1391 Str << "\tcltd"; | 1406 Str << "\tcltd"; |
| 1392 break; | 1407 break; |
| 1393 } | 1408 } |
| 1394 } | 1409 } |
| 1395 | 1410 |
| 1396 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { | 1411 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { |
| 1397 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1412 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1398 assert(getSrcSize() == 1); | 1413 assert(getSrcSize() == 1); |
| 1399 Operand *Src0 = getSrc(0); | 1414 Operand *Src0 = getSrc(0); |
| 1400 assert(llvm::isa<Variable>(Src0)); | 1415 assert(llvm::isa<Variable>(Src0)); |
| 1401 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1416 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
| 1402 switch (Src0->getType()) { | 1417 switch (Src0->getType()) { |
| 1403 default: | 1418 default: |
| 1404 llvm_unreachable("unexpected source type!"); | 1419 llvm_unreachable("unexpected source type!"); |
| 1405 break; | 1420 break; |
| 1406 case IceType_i8: | 1421 case IceType_i8: |
| 1407 assert(getDest()->getRegNum() == RegX8632::Reg_eax); | 1422 assert(getDest()->getRegNum() == RegX8632::Reg_eax); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1430 getSrc(1)->emit(Func); | 1445 getSrc(1)->emit(Func); |
| 1431 } | 1446 } |
| 1432 | 1447 |
| 1433 void InstX8632Mul::emitIAS(const Cfg *Func) const { | 1448 void InstX8632Mul::emitIAS(const Cfg *Func) const { |
| 1434 assert(getSrcSize() == 2); | 1449 assert(getSrcSize() == 2); |
| 1435 assert(llvm::isa<Variable>(getSrc(0))); | 1450 assert(llvm::isa<Variable>(getSrc(0))); |
| 1436 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1451 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
| 1437 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1452 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
| 1438 const Operand *Src = getSrc(1); | 1453 const Operand *Src = getSrc(1); |
| 1439 Type Ty = Src->getType(); | 1454 Type Ty = Src->getType(); |
| 1440 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1455 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
| 1441 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; | 1456 &X8632::AssemblerX8632::mul, &X8632::AssemblerX8632::mul}; |
| 1442 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1457 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| 1443 } | 1458 } |
| 1444 | 1459 |
| 1445 void InstX8632Mul::dump(const Cfg *Func) const { | 1460 void InstX8632Mul::dump(const Cfg *Func) const { |
| 1446 if (!ALLOW_DUMP) | 1461 if (!ALLOW_DUMP) |
| 1447 return; | 1462 return; |
| 1448 Ostream &Str = Func->getContext()->getStrDump(); | 1463 Ostream &Str = Func->getContext()->getStrDump(); |
| 1449 dumpDest(Func); | 1464 dumpDest(Func); |
| 1450 Str << " = mul." << getDest()->getType() << " "; | 1465 Str << " = mul." << getDest()->getType() << " "; |
| 1451 dumpSources(Func); | 1466 dumpSources(Func); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1471 Str << ", "; | 1486 Str << ", "; |
| 1472 Dest->emit(Func); | 1487 Dest->emit(Func); |
| 1473 } | 1488 } |
| 1474 | 1489 |
| 1475 void InstX8632Shld::emitIAS(const Cfg *Func) const { | 1490 void InstX8632Shld::emitIAS(const Cfg *Func) const { |
| 1476 assert(getSrcSize() == 3); | 1491 assert(getSrcSize() == 3); |
| 1477 assert(getDest() == getSrc(0)); | 1492 assert(getDest() == getSrc(0)); |
| 1478 const Variable *Dest = getDest(); | 1493 const Variable *Dest = getDest(); |
| 1479 const Operand *Src1 = getSrc(1); | 1494 const Operand *Src1 = getSrc(1); |
| 1480 const Operand *Src2 = getSrc(2); | 1495 const Operand *Src2 = getSrc(2); |
| 1481 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | 1496 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { |
| 1482 &x86::AssemblerX86::shld, &x86::AssemblerX86::shld}; | 1497 &X8632::AssemblerX8632::shld, &X8632::AssemblerX8632::shld}; |
| 1483 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1498 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); |
| 1484 } | 1499 } |
| 1485 | 1500 |
| 1486 void InstX8632Shld::dump(const Cfg *Func) const { | 1501 void InstX8632Shld::dump(const Cfg *Func) const { |
| 1487 if (!ALLOW_DUMP) | 1502 if (!ALLOW_DUMP) |
| 1488 return; | 1503 return; |
| 1489 Ostream &Str = Func->getContext()->getStrDump(); | 1504 Ostream &Str = Func->getContext()->getStrDump(); |
| 1490 dumpDest(Func); | 1505 dumpDest(Func); |
| 1491 Str << " = shld." << getDest()->getType() << " "; | 1506 Str << " = shld." << getDest()->getType() << " "; |
| 1492 dumpSources(Func); | 1507 dumpSources(Func); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1512 Str << ", "; | 1527 Str << ", "; |
| 1513 Dest->emit(Func); | 1528 Dest->emit(Func); |
| 1514 } | 1529 } |
| 1515 | 1530 |
| 1516 void InstX8632Shrd::emitIAS(const Cfg *Func) const { | 1531 void InstX8632Shrd::emitIAS(const Cfg *Func) const { |
| 1517 assert(getSrcSize() == 3); | 1532 assert(getSrcSize() == 3); |
| 1518 assert(getDest() == getSrc(0)); | 1533 assert(getDest() == getSrc(0)); |
| 1519 const Variable *Dest = getDest(); | 1534 const Variable *Dest = getDest(); |
| 1520 const Operand *Src1 = getSrc(1); | 1535 const Operand *Src1 = getSrc(1); |
| 1521 const Operand *Src2 = getSrc(2); | 1536 const Operand *Src2 = getSrc(2); |
| 1522 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | 1537 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { |
| 1523 &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd}; | 1538 &X8632::AssemblerX8632::shrd, &X8632::AssemblerX8632::shrd}; |
| 1524 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1539 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); |
| 1525 } | 1540 } |
| 1526 | 1541 |
| 1527 void InstX8632Shrd::dump(const Cfg *Func) const { | 1542 void InstX8632Shrd::dump(const Cfg *Func) const { |
| 1528 if (!ALLOW_DUMP) | 1543 if (!ALLOW_DUMP) |
| 1529 return; | 1544 return; |
| 1530 Ostream &Str = Func->getContext()->getStrDump(); | 1545 Ostream &Str = Func->getContext()->getStrDump(); |
| 1531 dumpDest(Func); | 1546 dumpDest(Func); |
| 1532 Str << " = shrd." << getDest()->getType() << " "; | 1547 Str << " = shrd." << getDest()->getType() << " "; |
| 1533 dumpSources(Func); | 1548 dumpSources(Func); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1549 } | 1564 } |
| 1550 | 1565 |
| 1551 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 1566 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
| 1552 assert(Condition != CondX86::Br_None); | 1567 assert(Condition != CondX86::Br_None); |
| 1553 assert(getDest()->hasReg()); | 1568 assert(getDest()->hasReg()); |
| 1554 assert(getSrcSize() == 2); | 1569 assert(getSrcSize() == 2); |
| 1555 // Only need the reg/reg form now. | 1570 // Only need the reg/reg form now. |
| 1556 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); | 1571 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
| 1557 assert(SrcVar->hasReg()); | 1572 assert(SrcVar->hasReg()); |
| 1558 assert(SrcVar->getType() == IceType_i32); | 1573 assert(SrcVar->getType() == IceType_i32); |
| 1559 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1574 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1560 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1575 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
| 1561 RegX8632::getEncodedGPR(SrcVar->getRegNum())); | 1576 RegX8632::getEncodedGPR(SrcVar->getRegNum())); |
| 1562 } | 1577 } |
| 1563 | 1578 |
| 1564 void InstX8632Cmov::dump(const Cfg *Func) const { | 1579 void InstX8632Cmov::dump(const Cfg *Func) const { |
| 1565 if (!ALLOW_DUMP) | 1580 if (!ALLOW_DUMP) |
| 1566 return; | 1581 return; |
| 1567 Ostream &Str = Func->getContext()->getStrDump(); | 1582 Ostream &Str = Func->getContext()->getStrDump(); |
| 1568 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 1583 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
| 1569 Str << getDest()->getType() << " "; | 1584 Str << getDest()->getType() << " "; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1580 assert(Condition < CondX86::Cmpps_Invalid); | 1595 assert(Condition < CondX86::Cmpps_Invalid); |
| 1581 Str << "\t"; | 1596 Str << "\t"; |
| 1582 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1597 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1583 << "\t"; | 1598 << "\t"; |
| 1584 getSrc(1)->emit(Func); | 1599 getSrc(1)->emit(Func); |
| 1585 Str << ", "; | 1600 Str << ", "; |
| 1586 getDest()->emit(Func); | 1601 getDest()->emit(Func); |
| 1587 } | 1602 } |
| 1588 | 1603 |
| 1589 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 1604 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
| 1590 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1605 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1591 assert(getSrcSize() == 2); | 1606 assert(getSrcSize() == 2); |
| 1592 assert(Condition < CondX86::Cmpps_Invalid); | 1607 assert(Condition < CondX86::Cmpps_Invalid); |
| 1593 // Assuming there isn't any load folding for cmpps, and vector constants | 1608 // Assuming there isn't any load folding for cmpps, and vector constants |
| 1594 // are not allowed in PNaCl. | 1609 // are not allowed in PNaCl. |
| 1595 assert(llvm::isa<Variable>(getSrc(1))); | 1610 assert(llvm::isa<Variable>(getSrc(1))); |
| 1596 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); | 1611 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
| 1597 if (SrcVar->hasReg()) { | 1612 if (SrcVar->hasReg()) { |
| 1598 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), | 1613 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), |
| 1599 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1614 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
| 1600 } else { | 1615 } else { |
| 1601 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1616 X8632::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 1602 ->stackVarToAsmOperand(SrcVar); | 1617 ->stackVarToAsmOperand(SrcVar); |
| 1603 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1618 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
| 1604 Condition); | 1619 Condition); |
| 1605 } | 1620 } |
| 1606 } | 1621 } |
| 1607 | 1622 |
| 1608 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1623 void InstX8632Cmpps::dump(const Cfg *Func) const { |
| 1609 if (!ALLOW_DUMP) | 1624 if (!ALLOW_DUMP) |
| 1610 return; | 1625 return; |
| 1611 Ostream &Str = Func->getContext()->getStrDump(); | 1626 Ostream &Str = Func->getContext()->getStrDump(); |
| 1612 assert(Condition < CondX86::Cmpps_Invalid); | 1627 assert(Condition < CondX86::Cmpps_Invalid); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1625 Str << "\tlock"; | 1640 Str << "\tlock"; |
| 1626 } | 1641 } |
| 1627 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 1642 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 1628 getSrc(2)->emit(Func); | 1643 getSrc(2)->emit(Func); |
| 1629 Str << ", "; | 1644 Str << ", "; |
| 1630 getSrc(0)->emit(Func); | 1645 getSrc(0)->emit(Func); |
| 1631 } | 1646 } |
| 1632 | 1647 |
| 1633 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1648 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
| 1634 assert(getSrcSize() == 3); | 1649 assert(getSrcSize() == 3); |
| 1635 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1650 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1636 Type Ty = getSrc(0)->getType(); | 1651 Type Ty = getSrc(0)->getType(); |
| 1637 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1652 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1638 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1653 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1639 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1654 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
| 1640 const auto VarReg = llvm::cast<Variable>(getSrc(2)); | 1655 const auto VarReg = llvm::cast<Variable>(getSrc(2)); |
| 1641 assert(VarReg->hasReg()); | 1656 assert(VarReg->hasReg()); |
| 1642 const RegX8632::GPRRegister Reg = | 1657 const RegX8632::GPRRegister Reg = |
| 1643 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1658 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 1644 Asm->cmpxchg(Ty, Addr, Reg, Locked); | 1659 Asm->cmpxchg(Ty, Addr, Reg, Locked); |
| 1645 } | 1660 } |
| 1646 | 1661 |
| 1647 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1662 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
| 1648 if (!ALLOW_DUMP) | 1663 if (!ALLOW_DUMP) |
| 1649 return; | 1664 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1662 assert(getSrcSize() == 5); | 1677 assert(getSrcSize() == 5); |
| 1663 if (Locked) { | 1678 if (Locked) { |
| 1664 Str << "\tlock"; | 1679 Str << "\tlock"; |
| 1665 } | 1680 } |
| 1666 Str << "\tcmpxchg8b\t"; | 1681 Str << "\tcmpxchg8b\t"; |
| 1667 getSrc(0)->emit(Func); | 1682 getSrc(0)->emit(Func); |
| 1668 } | 1683 } |
| 1669 | 1684 |
| 1670 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1685 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
| 1671 assert(getSrcSize() == 5); | 1686 assert(getSrcSize() == 5); |
| 1672 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1687 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1673 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1688 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1674 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1689 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1675 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1690 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
| 1676 Asm->cmpxchg8b(Addr, Locked); | 1691 Asm->cmpxchg8b(Addr, Locked); |
| 1677 } | 1692 } |
| 1678 | 1693 |
| 1679 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1694 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
| 1680 if (!ALLOW_DUMP) | 1695 if (!ALLOW_DUMP) |
| 1681 return; | 1696 return; |
| 1682 Ostream &Str = Func->getContext()->getStrDump(); | 1697 Ostream &Str = Func->getContext()->getStrDump(); |
| 1683 if (Locked) { | 1698 if (Locked) { |
| 1684 Str << "lock "; | 1699 Str << "lock "; |
| 1685 } | 1700 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1706 assert(getSrcSize() == 1); | 1721 assert(getSrcSize() == 1); |
| 1707 const Variable *Dest = getDest(); | 1722 const Variable *Dest = getDest(); |
| 1708 const Operand *Src = getSrc(0); | 1723 const Operand *Src = getSrc(0); |
| 1709 Type DestTy = Dest->getType(); | 1724 Type DestTy = Dest->getType(); |
| 1710 Type SrcTy = Src->getType(); | 1725 Type SrcTy = Src->getType(); |
| 1711 switch (Variant) { | 1726 switch (Variant) { |
| 1712 case Si2ss: { | 1727 case Si2ss: { |
| 1713 assert(isScalarIntegerType(SrcTy)); | 1728 assert(isScalarIntegerType(SrcTy)); |
| 1714 assert(typeWidthInBytes(SrcTy) <= 4); | 1729 assert(typeWidthInBytes(SrcTy) <= 4); |
| 1715 assert(isScalarFloatingType(DestTy)); | 1730 assert(isScalarFloatingType(DestTy)); |
| 1716 static const x86::AssemblerX86::CastEmitterRegOp< | 1731 static const X8632::AssemblerX8632::CastEmitterRegOp< |
| 1717 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { | 1732 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { |
| 1718 &x86::AssemblerX86::cvtsi2ss, &x86::AssemblerX86::cvtsi2ss}; | 1733 &X8632::AssemblerX8632::cvtsi2ss, &X8632::AssemblerX8632::cvtsi2ss}; |
| 1719 emitIASCastRegOp<RegX8632::XmmRegister, RegX8632::GPRRegister, | 1734 emitIASCastRegOp<RegX8632::XmmRegister, RegX8632::GPRRegister, |
| 1720 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( | 1735 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( |
| 1721 Func, DestTy, Dest, Src, Emitter); | 1736 Func, DestTy, Dest, Src, Emitter); |
| 1722 return; | 1737 return; |
| 1723 } | 1738 } |
| 1724 case Tss2si: { | 1739 case Tss2si: { |
| 1725 assert(isScalarFloatingType(SrcTy)); | 1740 assert(isScalarFloatingType(SrcTy)); |
| 1726 assert(isScalarIntegerType(DestTy)); | 1741 assert(isScalarIntegerType(DestTy)); |
| 1727 assert(typeWidthInBytes(DestTy) <= 4); | 1742 assert(typeWidthInBytes(DestTy) <= 4); |
| 1728 static const x86::AssemblerX86::CastEmitterRegOp< | 1743 static const X8632::AssemblerX8632::CastEmitterRegOp< |
| 1729 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | 1744 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { |
| 1730 &x86::AssemblerX86::cvttss2si, &x86::AssemblerX86::cvttss2si}; | 1745 &X8632::AssemblerX8632::cvttss2si, &X8632::AssemblerX8632::cvttss2si}; |
| 1731 emitIASCastRegOp<RegX8632::GPRRegister, RegX8632::XmmRegister, | 1746 emitIASCastRegOp<RegX8632::GPRRegister, RegX8632::XmmRegister, |
| 1732 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | 1747 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( |
| 1733 Func, SrcTy, Dest, Src, Emitter); | 1748 Func, SrcTy, Dest, Src, Emitter); |
| 1734 return; | 1749 return; |
| 1735 } | 1750 } |
| 1736 case Float2float: { | 1751 case Float2float: { |
| 1737 assert(isScalarFloatingType(SrcTy)); | 1752 assert(isScalarFloatingType(SrcTy)); |
| 1738 assert(isScalarFloatingType(DestTy)); | 1753 assert(isScalarFloatingType(DestTy)); |
| 1739 assert(DestTy != SrcTy); | 1754 assert(DestTy != SrcTy); |
| 1740 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1755 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1741 &x86::AssemblerX86::cvtfloat2float, &x86::AssemblerX86::cvtfloat2float}; | 1756 &X8632::AssemblerX8632::cvtfloat2float, |
| 1757 &X8632::AssemblerX8632::cvtfloat2float}; |
| 1742 emitIASRegOpTyXMM(Func, SrcTy, Dest, Src, Emitter); | 1758 emitIASRegOpTyXMM(Func, SrcTy, Dest, Src, Emitter); |
| 1743 return; | 1759 return; |
| 1744 } | 1760 } |
| 1745 case Dq2ps: { | 1761 case Dq2ps: { |
| 1746 assert(isVectorIntegerType(SrcTy)); | 1762 assert(isVectorIntegerType(SrcTy)); |
| 1747 assert(isVectorFloatingType(DestTy)); | 1763 assert(isVectorFloatingType(DestTy)); |
| 1748 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1764 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1749 &x86::AssemblerX86::cvtdq2ps, &x86::AssemblerX86::cvtdq2ps}; | 1765 &X8632::AssemblerX8632::cvtdq2ps, &X8632::AssemblerX8632::cvtdq2ps}; |
| 1750 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); | 1766 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); |
| 1751 return; | 1767 return; |
| 1752 } | 1768 } |
| 1753 case Tps2dq: { | 1769 case Tps2dq: { |
| 1754 assert(isVectorFloatingType(SrcTy)); | 1770 assert(isVectorFloatingType(SrcTy)); |
| 1755 assert(isVectorIntegerType(DestTy)); | 1771 assert(isVectorIntegerType(DestTy)); |
| 1756 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1772 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1757 &x86::AssemblerX86::cvttps2dq, &x86::AssemblerX86::cvttps2dq}; | 1773 &X8632::AssemblerX8632::cvttps2dq, &X8632::AssemblerX8632::cvttps2dq}; |
| 1758 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); | 1774 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); |
| 1759 return; | 1775 return; |
| 1760 } | 1776 } |
| 1761 } | 1777 } |
| 1762 } | 1778 } |
| 1763 | 1779 |
| 1764 void InstX8632Cvt::dump(const Cfg *Func) const { | 1780 void InstX8632Cvt::dump(const Cfg *Func) const { |
| 1765 if (!ALLOW_DUMP) | 1781 if (!ALLOW_DUMP) |
| 1766 return; | 1782 return; |
| 1767 Ostream &Str = Func->getContext()->getStrDump(); | 1783 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1783 getSrc(1)->emit(Func); | 1799 getSrc(1)->emit(Func); |
| 1784 Str << ", "; | 1800 Str << ", "; |
| 1785 getSrc(0)->emit(Func); | 1801 getSrc(0)->emit(Func); |
| 1786 } | 1802 } |
| 1787 | 1803 |
| 1788 void InstX8632Icmp::emitIAS(const Cfg *Func) const { | 1804 void InstX8632Icmp::emitIAS(const Cfg *Func) const { |
| 1789 assert(getSrcSize() == 2); | 1805 assert(getSrcSize() == 2); |
| 1790 const Operand *Src0 = getSrc(0); | 1806 const Operand *Src0 = getSrc(0); |
| 1791 const Operand *Src1 = getSrc(1); | 1807 const Operand *Src1 = getSrc(1); |
| 1792 Type Ty = Src0->getType(); | 1808 Type Ty = Src0->getType(); |
| 1793 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 1809 static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = { |
| 1794 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, | 1810 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp, |
| 1795 &x86::AssemblerX86::cmp}; | 1811 &X8632::AssemblerX8632::cmp}; |
| 1796 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { | 1812 static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = { |
| 1797 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp}; | 1813 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp}; |
| 1798 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 1814 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 1799 if (SrcVar0->hasReg()) { | 1815 if (SrcVar0->hasReg()) { |
| 1800 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1816 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1801 return; | 1817 return; |
| 1802 } | 1818 } |
| 1803 } | 1819 } |
| 1804 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); | 1820 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); |
| 1805 } | 1821 } |
| 1806 | 1822 |
| 1807 void InstX8632Icmp::dump(const Cfg *Func) const { | 1823 void InstX8632Icmp::dump(const Cfg *Func) const { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1824 getSrc(0)->emit(Func); | 1840 getSrc(0)->emit(Func); |
| 1825 } | 1841 } |
| 1826 | 1842 |
| 1827 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 1843 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
| 1828 assert(getSrcSize() == 2); | 1844 assert(getSrcSize() == 2); |
| 1829 // Currently src0 is always a variable by convention, to avoid having | 1845 // Currently src0 is always a variable by convention, to avoid having |
| 1830 // two memory operands. | 1846 // two memory operands. |
| 1831 assert(llvm::isa<Variable>(getSrc(0))); | 1847 assert(llvm::isa<Variable>(getSrc(0))); |
| 1832 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); | 1848 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); |
| 1833 Type Ty = Src0Var->getType(); | 1849 Type Ty = Src0Var->getType(); |
| 1834 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1850 const static X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1835 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss}; | 1851 &X8632::AssemblerX8632::ucomiss, &X8632::AssemblerX8632::ucomiss}; |
| 1836 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); | 1852 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); |
| 1837 } | 1853 } |
| 1838 | 1854 |
| 1839 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1855 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
| 1840 if (!ALLOW_DUMP) | 1856 if (!ALLOW_DUMP) |
| 1841 return; | 1857 return; |
| 1842 Ostream &Str = Func->getContext()->getStrDump(); | 1858 Ostream &Str = Func->getContext()->getStrDump(); |
| 1843 Str << "ucomiss." << getSrc(0)->getType() << " "; | 1859 Str << "ucomiss." << getSrc(0)->getType() << " "; |
| 1844 dumpSources(Func); | 1860 dumpSources(Func); |
| 1845 } | 1861 } |
| 1846 | 1862 |
| 1847 void InstX8632UD2::emit(const Cfg *Func) const { | 1863 void InstX8632UD2::emit(const Cfg *Func) const { |
| 1848 if (!ALLOW_DUMP) | 1864 if (!ALLOW_DUMP) |
| 1849 return; | 1865 return; |
| 1850 Ostream &Str = Func->getContext()->getStrEmit(); | 1866 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1851 assert(getSrcSize() == 0); | 1867 assert(getSrcSize() == 0); |
| 1852 Str << "\tud2"; | 1868 Str << "\tud2"; |
| 1853 } | 1869 } |
| 1854 | 1870 |
| 1855 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 1871 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
| 1856 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1872 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1857 Asm->ud2(); | 1873 Asm->ud2(); |
| 1858 } | 1874 } |
| 1859 | 1875 |
| 1860 void InstX8632UD2::dump(const Cfg *Func) const { | 1876 void InstX8632UD2::dump(const Cfg *Func) const { |
| 1861 if (!ALLOW_DUMP) | 1877 if (!ALLOW_DUMP) |
| 1862 return; | 1878 return; |
| 1863 Ostream &Str = Func->getContext()->getStrDump(); | 1879 Ostream &Str = Func->getContext()->getStrDump(); |
| 1864 Str << "ud2\n"; | 1880 Str << "ud2\n"; |
| 1865 } | 1881 } |
| 1866 | 1882 |
| 1867 void InstX8632Test::emit(const Cfg *Func) const { | 1883 void InstX8632Test::emit(const Cfg *Func) const { |
| 1868 if (!ALLOW_DUMP) | 1884 if (!ALLOW_DUMP) |
| 1869 return; | 1885 return; |
| 1870 Ostream &Str = Func->getContext()->getStrEmit(); | 1886 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1871 assert(getSrcSize() == 2); | 1887 assert(getSrcSize() == 2); |
| 1872 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; | 1888 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 1873 getSrc(1)->emit(Func); | 1889 getSrc(1)->emit(Func); |
| 1874 Str << ", "; | 1890 Str << ", "; |
| 1875 getSrc(0)->emit(Func); | 1891 getSrc(0)->emit(Func); |
| 1876 } | 1892 } |
| 1877 | 1893 |
| 1878 void InstX8632Test::emitIAS(const Cfg *Func) const { | 1894 void InstX8632Test::emitIAS(const Cfg *Func) const { |
| 1879 assert(getSrcSize() == 2); | 1895 assert(getSrcSize() == 2); |
| 1880 const Operand *Src0 = getSrc(0); | 1896 const Operand *Src0 = getSrc(0); |
| 1881 const Operand *Src1 = getSrc(1); | 1897 const Operand *Src1 = getSrc(1); |
| 1882 Type Ty = Src0->getType(); | 1898 Type Ty = Src0->getType(); |
| 1883 // The Reg/Addr form of test is not encodeable. | 1899 // The Reg/Addr form of test is not encodeable. |
| 1884 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 1900 static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = { |
| 1885 &x86::AssemblerX86::test, nullptr, &x86::AssemblerX86::test}; | 1901 &X8632::AssemblerX8632::test, nullptr, &X8632::AssemblerX8632::test}; |
| 1886 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { | 1902 static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = { |
| 1887 &x86::AssemblerX86::test, &x86::AssemblerX86::test}; | 1903 &X8632::AssemblerX8632::test, &X8632::AssemblerX8632::test}; |
| 1888 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 1904 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 1889 if (SrcVar0->hasReg()) { | 1905 if (SrcVar0->hasReg()) { |
| 1890 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1906 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1891 return; | 1907 return; |
| 1892 } | 1908 } |
| 1893 } | 1909 } |
| 1894 llvm_unreachable("Nothing actually generates this so it's untested"); | 1910 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1895 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); | 1911 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); |
| 1896 } | 1912 } |
| 1897 | 1913 |
| 1898 void InstX8632Test::dump(const Cfg *Func) const { | 1914 void InstX8632Test::dump(const Cfg *Func) const { |
| 1899 if (!ALLOW_DUMP) | 1915 if (!ALLOW_DUMP) |
| 1900 return; | 1916 return; |
| 1901 Ostream &Str = Func->getContext()->getStrDump(); | 1917 Ostream &Str = Func->getContext()->getStrDump(); |
| 1902 Str << "test." << getSrc(0)->getType() << " "; | 1918 Str << "test." << getSrc(0)->getType() << " "; |
| 1903 dumpSources(Func); | 1919 dumpSources(Func); |
| 1904 } | 1920 } |
| 1905 | 1921 |
| 1906 void InstX8632Mfence::emit(const Cfg *Func) const { | 1922 void InstX8632Mfence::emit(const Cfg *Func) const { |
| 1907 if (!ALLOW_DUMP) | 1923 if (!ALLOW_DUMP) |
| 1908 return; | 1924 return; |
| 1909 Ostream &Str = Func->getContext()->getStrEmit(); | 1925 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1910 assert(getSrcSize() == 0); | 1926 assert(getSrcSize() == 0); |
| 1911 Str << "\tmfence"; | 1927 Str << "\tmfence"; |
| 1912 } | 1928 } |
| 1913 | 1929 |
| 1914 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 1930 void InstX8632Mfence::emitIAS(const Cfg *Func) const { |
| 1915 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1931 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1916 Asm->mfence(); | 1932 Asm->mfence(); |
| 1917 } | 1933 } |
| 1918 | 1934 |
| 1919 void InstX8632Mfence::dump(const Cfg *Func) const { | 1935 void InstX8632Mfence::dump(const Cfg *Func) const { |
| 1920 if (!ALLOW_DUMP) | 1936 if (!ALLOW_DUMP) |
| 1921 return; | 1937 return; |
| 1922 Ostream &Str = Func->getContext()->getStrDump(); | 1938 Ostream &Str = Func->getContext()->getStrDump(); |
| 1923 Str << "mfence\n"; | 1939 Str << "mfence\n"; |
| 1924 } | 1940 } |
| 1925 | 1941 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1939 void InstX8632Store::emitIAS(const Cfg *Func) const { | 1955 void InstX8632Store::emitIAS(const Cfg *Func) const { |
| 1940 assert(getSrcSize() == 2); | 1956 assert(getSrcSize() == 2); |
| 1941 const Operand *Dest = getSrc(1); | 1957 const Operand *Dest = getSrc(1); |
| 1942 const Operand *Src = getSrc(0); | 1958 const Operand *Src = getSrc(0); |
| 1943 Type DestTy = Dest->getType(); | 1959 Type DestTy = Dest->getType(); |
| 1944 if (isScalarFloatingType(DestTy)) { | 1960 if (isScalarFloatingType(DestTy)) { |
| 1945 // Src must be a register, since Dest is a Mem operand of some kind. | 1961 // Src must be a register, since Dest is a Mem operand of some kind. |
| 1946 const auto SrcVar = llvm::cast<Variable>(Src); | 1962 const auto SrcVar = llvm::cast<Variable>(Src); |
| 1947 assert(SrcVar->hasReg()); | 1963 assert(SrcVar->hasReg()); |
| 1948 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 1964 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 1949 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1965 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1950 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { | 1966 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { |
| 1951 assert(!DestVar->hasReg()); | 1967 assert(!DestVar->hasReg()); |
| 1952 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1968 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1953 ->stackVarToAsmOperand(DestVar)); | 1969 ->stackVarToAsmOperand(DestVar)); |
| 1954 Asm->movss(DestTy, StackAddr, SrcReg); | 1970 Asm->movss(DestTy, StackAddr, SrcReg); |
| 1955 } else { | 1971 } else { |
| 1956 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest); | 1972 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest); |
| 1957 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1973 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1958 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg); | 1974 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg); |
| 1959 } | 1975 } |
| 1960 return; | 1976 return; |
| 1961 } else { | 1977 } else { |
| 1962 assert(isScalarIntegerType(DestTy)); | 1978 assert(isScalarIntegerType(DestTy)); |
| 1963 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { | 1979 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { |
| 1964 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; | 1980 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov}; |
| 1965 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); | 1981 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); |
| 1966 } | 1982 } |
| 1967 } | 1983 } |
| 1968 | 1984 |
| 1969 void InstX8632Store::dump(const Cfg *Func) const { | 1985 void InstX8632Store::dump(const Cfg *Func) const { |
| 1970 if (!ALLOW_DUMP) | 1986 if (!ALLOW_DUMP) |
| 1971 return; | 1987 return; |
| 1972 Ostream &Str = Func->getContext()->getStrDump(); | 1988 Ostream &Str = Func->getContext()->getStrDump(); |
| 1973 Str << "mov." << getSrc(0)->getType() << " "; | 1989 Str << "mov." << getSrc(0)->getType() << " "; |
| 1974 getSrc(1)->dump(Func); | 1990 getSrc(1)->dump(Func); |
| 1975 Str << ", "; | 1991 Str << ", "; |
| 1976 getSrc(0)->dump(Func); | 1992 getSrc(0)->dump(Func); |
| 1977 } | 1993 } |
| 1978 | 1994 |
| 1979 void InstX8632StoreP::emit(const Cfg *Func) const { | 1995 void InstX8632StoreP::emit(const Cfg *Func) const { |
| 1980 if (!ALLOW_DUMP) | 1996 if (!ALLOW_DUMP) |
| 1981 return; | 1997 return; |
| 1982 Ostream &Str = Func->getContext()->getStrEmit(); | 1998 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1983 assert(getSrcSize() == 2); | 1999 assert(getSrcSize() == 2); |
| 1984 Str << "\tmovups\t"; | 2000 Str << "\tmovups\t"; |
| 1985 getSrc(0)->emit(Func); | 2001 getSrc(0)->emit(Func); |
| 1986 Str << ", "; | 2002 Str << ", "; |
| 1987 getSrc(1)->emit(Func); | 2003 getSrc(1)->emit(Func); |
| 1988 } | 2004 } |
| 1989 | 2005 |
| 1990 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 2006 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
| 1991 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2007 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1992 assert(getSrcSize() == 2); | 2008 assert(getSrcSize() == 2); |
| 1993 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2009 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
| 1994 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2010 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1995 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2011 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1996 assert(SrcVar->hasReg()); | 2012 assert(SrcVar->hasReg()); |
| 1997 Asm->movups(DestMem->toAsmAddress(Asm), | 2013 Asm->movups(DestMem->toAsmAddress(Asm), |
| 1998 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2014 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 1999 } | 2015 } |
| 2000 | 2016 |
| 2001 void InstX8632StoreP::dump(const Cfg *Func) const { | 2017 void InstX8632StoreP::dump(const Cfg *Func) const { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2015 assert(getSrcSize() == 2); | 2031 assert(getSrcSize() == 2); |
| 2016 assert(getSrc(1)->getType() == IceType_i64 || | 2032 assert(getSrc(1)->getType() == IceType_i64 || |
| 2017 getSrc(1)->getType() == IceType_f64); | 2033 getSrc(1)->getType() == IceType_f64); |
| 2018 Str << "\tmovq\t"; | 2034 Str << "\tmovq\t"; |
| 2019 getSrc(0)->emit(Func); | 2035 getSrc(0)->emit(Func); |
| 2020 Str << ", "; | 2036 Str << ", "; |
| 2021 getSrc(1)->emit(Func); | 2037 getSrc(1)->emit(Func); |
| 2022 } | 2038 } |
| 2023 | 2039 |
| 2024 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 2040 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
| 2025 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2041 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2026 assert(getSrcSize() == 2); | 2042 assert(getSrcSize() == 2); |
| 2027 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2043 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
| 2028 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2044 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 2029 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2045 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2030 assert(SrcVar->hasReg()); | 2046 assert(SrcVar->hasReg()); |
| 2031 Asm->movq(DestMem->toAsmAddress(Asm), | 2047 Asm->movq(DestMem->toAsmAddress(Asm), |
| 2032 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2048 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 2033 } | 2049 } |
| 2034 | 2050 |
| 2035 void InstX8632StoreQ::dump(const Cfg *Func) const { | 2051 void InstX8632StoreQ::dump(const Cfg *Func) const { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2096 const Operand *Src = getSrc(0); | 2112 const Operand *Src = getSrc(0); |
| 2097 Type DestTy = Dest->getType(); | 2113 Type DestTy = Dest->getType(); |
| 2098 Type SrcTy = Src->getType(); | 2114 Type SrcTy = Src->getType(); |
| 2099 // Mov can be used for GPRs or XMM registers. Also, the type does not | 2115 // Mov can be used for GPRs or XMM registers. Also, the type does not |
| 2100 // necessarily match (Mov can be used for bitcasts). However, when | 2116 // necessarily match (Mov can be used for bitcasts). However, when |
| 2101 // the type does not match, one of the operands must be a register. | 2117 // the type does not match, one of the operands must be a register. |
| 2102 // Thus, the strategy is to find out if Src or Dest are a register, | 2118 // Thus, the strategy is to find out if Src or Dest are a register, |
| 2103 // then use that register's type to decide on which emitter set to use. | 2119 // then use that register's type to decide on which emitter set to use. |
| 2104 // The emitter set will include reg-reg movs, but that case should | 2120 // The emitter set will include reg-reg movs, but that case should |
| 2105 // be unused when the types don't match. | 2121 // be unused when the types don't match. |
| 2106 static const x86::AssemblerX86::XmmEmitterRegOp XmmRegEmitter = { | 2122 static const X8632::AssemblerX8632::XmmEmitterRegOp XmmRegEmitter = { |
| 2107 &x86::AssemblerX86::movss, &x86::AssemblerX86::movss}; | 2123 &X8632::AssemblerX8632::movss, &X8632::AssemblerX8632::movss}; |
| 2108 static const x86::AssemblerX86::GPREmitterRegOp GPRRegEmitter = { | 2124 static const X8632::AssemblerX8632::GPREmitterRegOp GPRRegEmitter = { |
| 2109 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov, | 2125 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov, |
| 2110 &x86::AssemblerX86::mov}; | 2126 &X8632::AssemblerX8632::mov}; |
| 2111 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { | 2127 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { |
| 2112 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; | 2128 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov}; |
| 2113 // For an integer truncation operation, src is wider than dest. | 2129 // For an integer truncation operation, src is wider than dest. |
| 2114 // Ideally, we use a mov instruction whose data width matches the | 2130 // Ideally, we use a mov instruction whose data width matches the |
| 2115 // narrower dest. This is a problem if e.g. src is a register like | 2131 // narrower dest. This is a problem if e.g. src is a register like |
| 2116 // esi or si where there is no 8-bit version of the register. To be | 2132 // esi or si where there is no 8-bit version of the register. To be |
| 2117 // safe, we instead widen the dest to match src. This works even | 2133 // safe, we instead widen the dest to match src. This works even |
| 2118 // for stack-allocated dest variables because typeWidthOnStack() | 2134 // for stack-allocated dest variables because typeWidthOnStack() |
| 2119 // pads to a 4-byte boundary even if only a lower portion is used. | 2135 // pads to a 4-byte boundary even if only a lower portion is used. |
| 2120 // TODO: This assert disallows usages such as copying a floating point | 2136 // TODO: This assert disallows usages such as copying a floating point |
| 2121 // value between a vector and a scalar (which movss is used for). | 2137 // value between a vector and a scalar (which movss is used for). |
| 2122 // Clean this up. | 2138 // Clean this up. |
| 2123 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == | 2139 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == |
| 2124 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); | 2140 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
| 2125 if (Dest->hasReg()) { | 2141 if (Dest->hasReg()) { |
| 2126 if (isScalarFloatingType(DestTy)) { | 2142 if (isScalarFloatingType(DestTy)) { |
| 2127 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter); | 2143 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter); |
| 2128 return; | 2144 return; |
| 2129 } else { | 2145 } else { |
| 2130 assert(isScalarIntegerType(DestTy)); | 2146 assert(isScalarIntegerType(DestTy)); |
| 2131 // Widen DestTy for truncation (see above note). We should only do this | 2147 // Widen DestTy for truncation (see above note). We should only do this |
| 2132 // when both Src and Dest are integer types. | 2148 // when both Src and Dest are integer types. |
| 2133 if (isScalarIntegerType(SrcTy)) { | 2149 if (isScalarIntegerType(SrcTy)) { |
| 2134 DestTy = SrcTy; | 2150 DestTy = SrcTy; |
| 2135 } | 2151 } |
| 2136 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); | 2152 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 2137 return; | 2153 return; |
| 2138 } | 2154 } |
| 2139 } else { | 2155 } else { |
| 2140 // Dest must be Stack and Src *could* be a register. Use Src's type | 2156 // Dest must be Stack and Src *could* be a register. Use Src's type |
| 2141 // to decide on the emitters. | 2157 // to decide on the emitters. |
| 2142 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2158 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2143 ->stackVarToAsmOperand(Dest)); | 2159 ->stackVarToAsmOperand(Dest)); |
| 2144 if (isScalarFloatingType(SrcTy)) { | 2160 if (isScalarFloatingType(SrcTy)) { |
| 2145 // Src must be a register. | 2161 // Src must be a register. |
| 2146 const auto SrcVar = llvm::cast<Variable>(Src); | 2162 const auto SrcVar = llvm::cast<Variable>(Src); |
| 2147 assert(SrcVar->hasReg()); | 2163 assert(SrcVar->hasReg()); |
| 2148 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2164 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2149 Asm->movss(SrcTy, StackAddr, | 2165 Asm->movss(SrcTy, StackAddr, |
| 2150 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2166 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 2151 return; | 2167 return; |
| 2152 } else { | 2168 } else { |
| 2153 // Src can be a register or immediate. | 2169 // Src can be a register or immediate. |
| 2154 assert(isScalarIntegerType(SrcTy)); | 2170 assert(isScalarIntegerType(SrcTy)); |
| 2155 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); | 2171 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); |
| 2156 return; | 2172 return; |
| 2157 } | 2173 } |
| 2158 return; | 2174 return; |
| 2159 } | 2175 } |
| 2160 } | 2176 } |
| 2161 | 2177 |
| 2162 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { | 2178 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { |
| 2163 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2179 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2164 assert(getSrcSize() == 1); | 2180 assert(getSrcSize() == 1); |
| 2165 const Variable *Dest = getDest(); | 2181 const Variable *Dest = getDest(); |
| 2166 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2182 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
| 2167 // For insert/extract element (one of Src/Dest is an Xmm vector and | 2183 // For insert/extract element (one of Src/Dest is an Xmm vector and |
| 2168 // the other is an int type). | 2184 // the other is an int type). |
| 2169 if (SrcVar->getType() == IceType_i32) { | 2185 if (SrcVar->getType() == IceType_i32) { |
| 2170 assert(isVectorType(Dest->getType())); | 2186 assert(isVectorType(Dest->getType())); |
| 2171 assert(Dest->hasReg()); | 2187 assert(Dest->hasReg()); |
| 2172 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 2188 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 2173 if (SrcVar->hasReg()) { | 2189 if (SrcVar->hasReg()) { |
| 2174 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum())); | 2190 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum())); |
| 2175 } else { | 2191 } else { |
| 2176 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2192 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2177 ->stackVarToAsmOperand(SrcVar)); | 2193 ->stackVarToAsmOperand(SrcVar)); |
| 2178 Asm->movd(DestReg, StackAddr); | 2194 Asm->movd(DestReg, StackAddr); |
| 2179 } | 2195 } |
| 2180 } else { | 2196 } else { |
| 2181 assert(isVectorType(SrcVar->getType())); | 2197 assert(isVectorType(SrcVar->getType())); |
| 2182 assert(SrcVar->hasReg()); | 2198 assert(SrcVar->hasReg()); |
| 2183 assert(Dest->getType() == IceType_i32); | 2199 assert(Dest->getType() == IceType_i32); |
| 2184 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 2200 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 2185 if (Dest->hasReg()) { | 2201 if (Dest->hasReg()) { |
| 2186 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); | 2202 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); |
| 2187 } else { | 2203 } else { |
| 2188 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2204 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2189 ->stackVarToAsmOperand(Dest)); | 2205 ->stackVarToAsmOperand(Dest)); |
| 2190 Asm->movd(StackAddr, SrcReg); | 2206 Asm->movd(StackAddr, SrcReg); |
| 2191 } | 2207 } |
| 2192 } | 2208 } |
| 2193 } | 2209 } |
| 2194 | 2210 |
| 2195 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 2211 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
| 2196 if (!ALLOW_DUMP) | 2212 if (!ALLOW_DUMP) |
| 2197 return; | 2213 return; |
| 2198 // TODO(wala,stichnot): movups works with all vector operands, but | 2214 // TODO(wala,stichnot): movups works with all vector operands, but |
| 2199 // there exist other instructions (movaps, movdqa, movdqu) that may | 2215 // there exist other instructions (movaps, movdqa, movdqu) that may |
| 2200 // perform better, depending on the data type and alignment of the | 2216 // perform better, depending on the data type and alignment of the |
| 2201 // operands. | 2217 // operands. |
| 2202 Ostream &Str = Func->getContext()->getStrEmit(); | 2218 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2203 assert(getSrcSize() == 1); | 2219 assert(getSrcSize() == 1); |
| 2204 Str << "\tmovups\t"; | 2220 Str << "\tmovups\t"; |
| 2205 getSrc(0)->emit(Func); | 2221 getSrc(0)->emit(Func); |
| 2206 Str << ", "; | 2222 Str << ", "; |
| 2207 getDest()->emit(Func); | 2223 getDest()->emit(Func); |
| 2208 } | 2224 } |
| 2209 | 2225 |
| 2210 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { | 2226 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { |
| 2211 assert(getSrcSize() == 1); | 2227 assert(getSrcSize() == 1); |
| 2212 assert(isVectorType(getDest()->getType())); | 2228 assert(isVectorType(getDest()->getType())); |
| 2213 const Variable *Dest = getDest(); | 2229 const Variable *Dest = getDest(); |
| 2214 const Operand *Src = getSrc(0); | 2230 const Operand *Src = getSrc(0); |
| 2215 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { | 2231 const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = { |
| 2216 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, | 2232 &X8632::AssemblerX8632::movups, &X8632::AssemblerX8632::movups, |
| 2217 &x86::AssemblerX86::movups}; | 2233 &X8632::AssemblerX8632::movups}; |
| 2218 emitIASMovlikeXMM(Func, Dest, Src, Emitter); | 2234 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
| 2219 } | 2235 } |
| 2220 | 2236 |
| 2221 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 2237 template <> void InstX8632Movq::emit(const Cfg *Func) const { |
| 2222 if (!ALLOW_DUMP) | 2238 if (!ALLOW_DUMP) |
| 2223 return; | 2239 return; |
| 2224 Ostream &Str = Func->getContext()->getStrEmit(); | 2240 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2225 assert(getSrcSize() == 1); | 2241 assert(getSrcSize() == 1); |
| 2226 assert(getDest()->getType() == IceType_i64 || | 2242 assert(getDest()->getType() == IceType_i64 || |
| 2227 getDest()->getType() == IceType_f64); | 2243 getDest()->getType() == IceType_f64); |
| 2228 Str << "\tmovq\t"; | 2244 Str << "\tmovq\t"; |
| 2229 getSrc(0)->emit(Func); | 2245 getSrc(0)->emit(Func); |
| 2230 Str << ", "; | 2246 Str << ", "; |
| 2231 getDest()->emit(Func); | 2247 getDest()->emit(Func); |
| 2232 } | 2248 } |
| 2233 | 2249 |
| 2234 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { | 2250 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { |
| 2235 assert(getSrcSize() == 1); | 2251 assert(getSrcSize() == 1); |
| 2236 assert(getDest()->getType() == IceType_i64 || | 2252 assert(getDest()->getType() == IceType_i64 || |
| 2237 getDest()->getType() == IceType_f64); | 2253 getDest()->getType() == IceType_f64); |
| 2238 const Variable *Dest = getDest(); | 2254 const Variable *Dest = getDest(); |
| 2239 const Operand *Src = getSrc(0); | 2255 const Operand *Src = getSrc(0); |
| 2240 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { | 2256 const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = { |
| 2241 &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, | 2257 &X8632::AssemblerX8632::movq, &X8632::AssemblerX8632::movq, |
| 2242 &x86::AssemblerX86::movq}; | 2258 &X8632::AssemblerX8632::movq}; |
| 2243 emitIASMovlikeXMM(Func, Dest, Src, Emitter); | 2259 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
| 2244 } | 2260 } |
| 2245 | 2261 |
| 2246 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { | 2262 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { |
| 2247 // This is Binop variant is only intended to be used for reg-reg moves | 2263 // This is Binop variant is only intended to be used for reg-reg moves |
| 2248 // where part of the Dest register is untouched. | 2264 // where part of the Dest register is untouched. |
| 2249 assert(getSrcSize() == 2); | 2265 assert(getSrcSize() == 2); |
| 2250 const Variable *Dest = getDest(); | 2266 const Variable *Dest = getDest(); |
| 2251 assert(Dest == getSrc(0)); | 2267 assert(Dest == getSrc(0)); |
| 2252 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); | 2268 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
| 2253 assert(Dest->hasReg() && SrcVar->hasReg()); | 2269 assert(Dest->hasReg() && SrcVar->hasReg()); |
| 2254 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2270 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2255 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), | 2271 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), |
| 2256 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2272 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 2257 } | 2273 } |
| 2258 | 2274 |
| 2259 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const { | 2275 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const { |
| 2260 assert(getSrcSize() == 1); | 2276 assert(getSrcSize() == 1); |
| 2261 const Variable *Dest = getDest(); | 2277 const Variable *Dest = getDest(); |
| 2262 const Operand *Src = getSrc(0); | 2278 const Operand *Src = getSrc(0); |
| 2263 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice | 2279 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice |
| 2264 // we just use the full register for Dest to avoid having an | 2280 // we just use the full register for Dest to avoid having an |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2281 | 2297 |
| 2282 void InstX8632Nop::emit(const Cfg *Func) const { | 2298 void InstX8632Nop::emit(const Cfg *Func) const { |
| 2283 if (!ALLOW_DUMP) | 2299 if (!ALLOW_DUMP) |
| 2284 return; | 2300 return; |
| 2285 Ostream &Str = Func->getContext()->getStrEmit(); | 2301 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2286 // TODO: Emit the right code for each variant. | 2302 // TODO: Emit the right code for each variant. |
| 2287 Str << "\tnop\t# variant = " << Variant; | 2303 Str << "\tnop\t# variant = " << Variant; |
| 2288 } | 2304 } |
| 2289 | 2305 |
| 2290 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 2306 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
| 2291 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2307 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2292 // TODO: Emit the right code for the variant. | 2308 // TODO: Emit the right code for the variant. |
| 2293 Asm->nop(); | 2309 Asm->nop(); |
| 2294 } | 2310 } |
| 2295 | 2311 |
| 2296 void InstX8632Nop::dump(const Cfg *Func) const { | 2312 void InstX8632Nop::dump(const Cfg *Func) const { |
| 2297 if (!ALLOW_DUMP) | 2313 if (!ALLOW_DUMP) |
| 2298 return; | 2314 return; |
| 2299 Ostream &Str = Func->getContext()->getStrDump(); | 2315 Ostream &Str = Func->getContext()->getStrDump(); |
| 2300 Str << "nop (variant = " << Variant << ")"; | 2316 Str << "nop (variant = " << Variant << ")"; |
| 2301 } | 2317 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2319 Str << "\tfld" << getFldString(Ty) << "\t" | 2335 Str << "\tfld" << getFldString(Ty) << "\t" |
| 2320 << "(%esp)\n"; | 2336 << "(%esp)\n"; |
| 2321 Str << "\taddl\t$" << Width << ", %esp"; | 2337 Str << "\taddl\t$" << Width << ", %esp"; |
| 2322 return; | 2338 return; |
| 2323 } | 2339 } |
| 2324 Str << "\tfld" << getFldString(Ty) << "\t"; | 2340 Str << "\tfld" << getFldString(Ty) << "\t"; |
| 2325 getSrc(0)->emit(Func); | 2341 getSrc(0)->emit(Func); |
| 2326 } | 2342 } |
| 2327 | 2343 |
| 2328 void InstX8632Fld::emitIAS(const Cfg *Func) const { | 2344 void InstX8632Fld::emitIAS(const Cfg *Func) const { |
| 2329 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2345 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2330 assert(getSrcSize() == 1); | 2346 assert(getSrcSize() == 1); |
| 2331 const Operand *Src = getSrc(0); | 2347 const Operand *Src = getSrc(0); |
| 2332 Type Ty = Src->getType(); | 2348 Type Ty = Src->getType(); |
| 2333 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { | 2349 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { |
| 2334 if (Var->hasReg()) { | 2350 if (Var->hasReg()) { |
| 2335 // This is a physical xmm register, so we need to spill it to a | 2351 // This is a physical xmm register, so we need to spill it to a |
| 2336 // temporary stack slot. | 2352 // temporary stack slot. |
| 2337 x86::Immediate Width(typeWidthInBytes(Ty)); | 2353 X8632::Immediate Width(typeWidthInBytes(Ty)); |
| 2338 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2354 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2339 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2355 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2340 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); | 2356 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); |
| 2341 Asm->fld(Ty, StackSlot); | 2357 Asm->fld(Ty, StackSlot); |
| 2342 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2358 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2343 } else { | 2359 } else { |
| 2344 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2360 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2345 ->stackVarToAsmOperand(Var)); | 2361 ->stackVarToAsmOperand(Var)); |
| 2346 Asm->fld(Ty, StackAddr); | 2362 Asm->fld(Ty, StackAddr); |
| 2347 } | 2363 } |
| 2348 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 2364 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 2349 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2365 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2350 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2366 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
| 2351 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2367 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
| 2352 Asm->fld(Ty, x86::Address::ofConstPool(Asm, Imm)); | 2368 Asm->fld(Ty, X8632::Address::ofConstPool(Asm, Imm)); |
| 2353 } else { | 2369 } else { |
| 2354 llvm_unreachable("Unexpected operand type"); | 2370 llvm_unreachable("Unexpected operand type"); |
| 2355 } | 2371 } |
| 2356 } | 2372 } |
| 2357 | 2373 |
| 2358 void InstX8632Fld::dump(const Cfg *Func) const { | 2374 void InstX8632Fld::dump(const Cfg *Func) const { |
| 2359 if (!ALLOW_DUMP) | 2375 if (!ALLOW_DUMP) |
| 2360 return; | 2376 return; |
| 2361 Ostream &Str = Func->getContext()->getStrDump(); | 2377 Ostream &Str = Func->getContext()->getStrDump(); |
| 2362 Str << "fld." << getSrc(0)->getType() << " "; | 2378 Str << "fld." << getSrc(0)->getType() << " "; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2391 Str << "\tfstp" << getFldString(Ty) << "\t" | 2407 Str << "\tfstp" << getFldString(Ty) << "\t" |
| 2392 << "(%esp)\n"; | 2408 << "(%esp)\n"; |
| 2393 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" | 2409 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" |
| 2394 << "(%esp), "; | 2410 << "(%esp), "; |
| 2395 getDest()->emit(Func); | 2411 getDest()->emit(Func); |
| 2396 Str << "\n"; | 2412 Str << "\n"; |
| 2397 Str << "\taddl\t$" << Width << ", %esp"; | 2413 Str << "\taddl\t$" << Width << ", %esp"; |
| 2398 } | 2414 } |
| 2399 | 2415 |
| 2400 void InstX8632Fstp::emitIAS(const Cfg *Func) const { | 2416 void InstX8632Fstp::emitIAS(const Cfg *Func) const { |
| 2401 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2417 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2402 assert(getSrcSize() == 0); | 2418 assert(getSrcSize() == 0); |
| 2403 const Variable *Dest = getDest(); | 2419 const Variable *Dest = getDest(); |
| 2404 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2420 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
| 2405 // "partially" delete the fstp if the Dest is unused. | 2421 // "partially" delete the fstp if the Dest is unused. |
| 2406 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2422 // Even if Dest is unused, the fstp should be kept for the SideEffects |
| 2407 // of popping the stack. | 2423 // of popping the stack. |
| 2408 if (!Dest) { | 2424 if (!Dest) { |
| 2409 Asm->fstp(RegX8632::getEncodedSTReg(0)); | 2425 Asm->fstp(RegX8632::getEncodedSTReg(0)); |
| 2410 return; | 2426 return; |
| 2411 } | 2427 } |
| 2412 Type Ty = Dest->getType(); | 2428 Type Ty = Dest->getType(); |
| 2413 if (!Dest->hasReg()) { | 2429 if (!Dest->hasReg()) { |
| 2414 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2430 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2415 ->stackVarToAsmOperand(Dest)); | 2431 ->stackVarToAsmOperand(Dest)); |
| 2416 Asm->fstp(Ty, StackAddr); | 2432 Asm->fstp(Ty, StackAddr); |
| 2417 } else { | 2433 } else { |
| 2418 // Dest is a physical (xmm) register, so st(0) needs to go through | 2434 // Dest is a physical (xmm) register, so st(0) needs to go through |
| 2419 // memory. Hack this by creating a temporary stack slot, spilling | 2435 // memory. Hack this by creating a temporary stack slot, spilling |
| 2420 // st(0) there, loading it into the xmm register, and deallocating | 2436 // st(0) there, loading it into the xmm register, and deallocating |
| 2421 // the stack slot. | 2437 // the stack slot. |
| 2422 x86::Immediate Width(typeWidthInBytes(Ty)); | 2438 X8632::Immediate Width(typeWidthInBytes(Ty)); |
| 2423 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2439 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2424 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2440 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2425 Asm->fstp(Ty, StackSlot); | 2441 Asm->fstp(Ty, StackSlot); |
| 2426 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); | 2442 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); |
| 2427 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2443 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2428 } | 2444 } |
| 2429 } | 2445 } |
| 2430 | 2446 |
| 2431 void InstX8632Fstp::dump(const Cfg *Func) const { | 2447 void InstX8632Fstp::dump(const Cfg *Func) const { |
| 2432 if (!ALLOW_DUMP) | 2448 if (!ALLOW_DUMP) |
| 2433 return; | 2449 return; |
| 2434 Ostream &Str = Func->getContext()->getStrDump(); | 2450 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2486 Type DispatchTy = Dest->getType(); | 2502 Type DispatchTy = Dest->getType(); |
| 2487 assert(DispatchTy == IceType_i16 || | 2503 assert(DispatchTy == IceType_i16 || |
| 2488 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2504 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 2489 TargetX8632::SSE4_1); | 2505 TargetX8632::SSE4_1); |
| 2490 // pextrw must take a register dest. There is an SSE4.1 version that takes | 2506 // pextrw must take a register dest. There is an SSE4.1 version that takes |
| 2491 // a memory dest, but we aren't using it. For uniformity, just restrict | 2507 // a memory dest, but we aren't using it. For uniformity, just restrict |
| 2492 // them all to have a register dest for now. | 2508 // them all to have a register dest for now. |
| 2493 assert(Dest->hasReg()); | 2509 assert(Dest->hasReg()); |
| 2494 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). | 2510 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). |
| 2495 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); | 2511 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); |
| 2496 static const x86::AssemblerX86::ThreeOpImmEmitter< | 2512 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 2497 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | 2513 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { |
| 2498 &x86::AssemblerX86::pextr, nullptr}; | 2514 &X8632::AssemblerX8632::pextr, nullptr}; |
| 2499 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, | 2515 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, |
| 2500 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | 2516 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( |
| 2501 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); | 2517 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); |
| 2502 } | 2518 } |
| 2503 | 2519 |
| 2504 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { | 2520 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { |
| 2505 if (!ALLOW_DUMP) | 2521 if (!ALLOW_DUMP) |
| 2506 return; | 2522 return; |
| 2507 Ostream &Str = Func->getContext()->getStrEmit(); | 2523 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2508 assert(getSrcSize() == 3); | 2524 assert(getSrcSize() == 3); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2536 // pinsrb and pinsrd are SSE4.1 instructions. | 2552 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2537 const Operand *Src0 = getSrc(1); | 2553 const Operand *Src0 = getSrc(1); |
| 2538 Type DispatchTy = Src0->getType(); | 2554 Type DispatchTy = Src0->getType(); |
| 2539 assert(DispatchTy == IceType_i16 || | 2555 assert(DispatchTy == IceType_i16 || |
| 2540 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2556 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 2541 TargetX8632::SSE4_1); | 2557 TargetX8632::SSE4_1); |
| 2542 // If src1 is a register, it should always be r32 (this should fall out | 2558 // If src1 is a register, it should always be r32 (this should fall out |
| 2543 // from the encodings for ByteRegs overlapping the encodings for r32), | 2559 // from the encodings for ByteRegs overlapping the encodings for r32), |
| 2544 // but we have to trust the regalloc to not choose "ah", where it | 2560 // but we have to trust the regalloc to not choose "ah", where it |
| 2545 // doesn't overlap. | 2561 // doesn't overlap. |
| 2546 static const x86::AssemblerX86::ThreeOpImmEmitter< | 2562 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 2547 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { | 2563 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { |
| 2548 &x86::AssemblerX86::pinsr, &x86::AssemblerX86::pinsr}; | 2564 &X8632::AssemblerX8632::pinsr, &X8632::AssemblerX8632::pinsr}; |
| 2549 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::GPRRegister, | 2565 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::GPRRegister, |
| 2550 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( | 2566 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( |
| 2551 Func, DispatchTy, getDest(), Src0, getSrc(2), Emitter); | 2567 Func, DispatchTy, getDest(), Src0, getSrc(2), Emitter); |
| 2552 } | 2568 } |
| 2553 | 2569 |
| 2554 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const { | 2570 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const { |
| 2555 assert(getSrcSize() == 2); | 2571 assert(getSrcSize() == 2); |
| 2556 const Variable *Dest = getDest(); | 2572 const Variable *Dest = getDest(); |
| 2557 Type Ty = Dest->getType(); | 2573 Type Ty = Dest->getType(); |
| 2558 static const x86::AssemblerX86::ThreeOpImmEmitter< | 2574 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 2559 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 2575 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
| 2560 &x86::AssemblerX86::pshufd, &x86::AssemblerX86::pshufd}; | 2576 &X8632::AssemblerX8632::pshufd, &X8632::AssemblerX8632::pshufd}; |
| 2561 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 2577 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
| 2562 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 2578 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
| 2563 Func, Ty, Dest, getSrc(0), getSrc(1), Emitter); | 2579 Func, Ty, Dest, getSrc(0), getSrc(1), Emitter); |
| 2564 } | 2580 } |
| 2565 | 2581 |
| 2566 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const { | 2582 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const { |
| 2567 assert(getSrcSize() == 3); | 2583 assert(getSrcSize() == 3); |
| 2568 const Variable *Dest = getDest(); | 2584 const Variable *Dest = getDest(); |
| 2569 assert(Dest == getSrc(0)); | 2585 assert(Dest == getSrc(0)); |
| 2570 Type Ty = Dest->getType(); | 2586 Type Ty = Dest->getType(); |
| 2571 static const x86::AssemblerX86::ThreeOpImmEmitter< | 2587 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 2572 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 2588 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
| 2573 &x86::AssemblerX86::shufps, &x86::AssemblerX86::shufps}; | 2589 &X8632::AssemblerX8632::shufps, &X8632::AssemblerX8632::shufps}; |
| 2574 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 2590 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
| 2575 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 2591 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
| 2576 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 2592 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
| 2577 } | 2593 } |
| 2578 | 2594 |
| 2579 void InstX8632Pop::emit(const Cfg *Func) const { | 2595 void InstX8632Pop::emit(const Cfg *Func) const { |
| 2580 if (!ALLOW_DUMP) | 2596 if (!ALLOW_DUMP) |
| 2581 return; | 2597 return; |
| 2582 Ostream &Str = Func->getContext()->getStrEmit(); | 2598 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2583 assert(getSrcSize() == 0); | 2599 assert(getSrcSize() == 0); |
| 2584 Str << "\tpop\t"; | 2600 Str << "\tpop\t"; |
| 2585 getDest()->emit(Func); | 2601 getDest()->emit(Func); |
| 2586 } | 2602 } |
| 2587 | 2603 |
| 2588 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2604 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
| 2589 assert(getSrcSize() == 0); | 2605 assert(getSrcSize() == 0); |
| 2590 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2606 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2591 if (getDest()->hasReg()) { | 2607 if (getDest()->hasReg()) { |
| 2592 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 2608 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); |
| 2593 } else { | 2609 } else { |
| 2594 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 2610 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2595 ->stackVarToAsmOperand(getDest())); | 2611 ->stackVarToAsmOperand(getDest())); |
| 2596 } | 2612 } |
| 2597 } | 2613 } |
| 2598 | 2614 |
| 2599 void InstX8632Pop::dump(const Cfg *Func) const { | 2615 void InstX8632Pop::dump(const Cfg *Func) const { |
| 2600 if (!ALLOW_DUMP) | 2616 if (!ALLOW_DUMP) |
| 2601 return; | 2617 return; |
| 2602 Ostream &Str = Func->getContext()->getStrDump(); | 2618 Ostream &Str = Func->getContext()->getStrDump(); |
| 2603 dumpDest(Func); | 2619 dumpDest(Func); |
| 2604 Str << " = pop." << getDest()->getType() << " "; | 2620 Str << " = pop." << getDest()->getType() << " "; |
| 2605 } | 2621 } |
| 2606 | 2622 |
| 2607 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 2623 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
| 2608 if (!ALLOW_DUMP) | 2624 if (!ALLOW_DUMP) |
| 2609 return; | 2625 return; |
| 2610 Ostream &Str = Func->getContext()->getStrEmit(); | 2626 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2611 Str << "\tsubl\t$" << Amount << ", %esp"; | 2627 Str << "\tsubl\t$" << Amount << ", %esp"; |
| 2612 Func->getTarget()->updateStackAdjustment(Amount); | 2628 Func->getTarget()->updateStackAdjustment(Amount); |
| 2613 } | 2629 } |
| 2614 | 2630 |
| 2615 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 2631 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
| 2616 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2632 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2617 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); | 2633 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, X8632::Immediate(Amount)); |
| 2618 Func->getTarget()->updateStackAdjustment(Amount); | 2634 Func->getTarget()->updateStackAdjustment(Amount); |
| 2619 } | 2635 } |
| 2620 | 2636 |
| 2621 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 2637 void InstX8632AdjustStack::dump(const Cfg *Func) const { |
| 2622 if (!ALLOW_DUMP) | 2638 if (!ALLOW_DUMP) |
| 2623 return; | 2639 return; |
| 2624 Ostream &Str = Func->getContext()->getStrDump(); | 2640 Ostream &Str = Func->getContext()->getStrDump(); |
| 2625 Str << "esp = sub.i32 esp, " << Amount; | 2641 Str << "esp = sub.i32 esp, " << Amount; |
| 2626 } | 2642 } |
| 2627 | 2643 |
| 2628 void InstX8632Push::emit(const Cfg *Func) const { | 2644 void InstX8632Push::emit(const Cfg *Func) const { |
| 2629 if (!ALLOW_DUMP) | 2645 if (!ALLOW_DUMP) |
| 2630 return; | 2646 return; |
| 2631 Ostream &Str = Func->getContext()->getStrEmit(); | 2647 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2632 assert(getSrcSize() == 1); | 2648 assert(getSrcSize() == 1); |
| 2633 // Push is currently only used for saving GPRs. | 2649 // Push is currently only used for saving GPRs. |
| 2634 const auto Var = llvm::cast<Variable>(getSrc(0)); | 2650 const auto Var = llvm::cast<Variable>(getSrc(0)); |
| 2635 assert(Var->hasReg()); | 2651 assert(Var->hasReg()); |
| 2636 Str << "\tpush\t"; | 2652 Str << "\tpush\t"; |
| 2637 Var->emit(Func); | 2653 Var->emit(Func); |
| 2638 } | 2654 } |
| 2639 | 2655 |
| 2640 void InstX8632Push::emitIAS(const Cfg *Func) const { | 2656 void InstX8632Push::emitIAS(const Cfg *Func) const { |
| 2641 assert(getSrcSize() == 1); | 2657 assert(getSrcSize() == 1); |
| 2642 // Push is currently only used for saving GPRs. | 2658 // Push is currently only used for saving GPRs. |
| 2643 const auto Var = llvm::cast<Variable>(getSrc(0)); | 2659 const auto Var = llvm::cast<Variable>(getSrc(0)); |
| 2644 assert(Var->hasReg()); | 2660 assert(Var->hasReg()); |
| 2645 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2661 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2646 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 2662 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); |
| 2647 } | 2663 } |
| 2648 | 2664 |
| 2649 void InstX8632Push::dump(const Cfg *Func) const { | 2665 void InstX8632Push::dump(const Cfg *Func) const { |
| 2650 if (!ALLOW_DUMP) | 2666 if (!ALLOW_DUMP) |
| 2651 return; | 2667 return; |
| 2652 Ostream &Str = Func->getContext()->getStrDump(); | 2668 Ostream &Str = Func->getContext()->getStrDump(); |
| 2653 Str << "push." << getSrc(0)->getType() << " "; | 2669 Str << "push." << getSrc(0)->getType() << " "; |
| 2654 dumpSources(Func); | 2670 dumpSources(Func); |
| 2655 } | 2671 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2690 } | 2706 } |
| 2691 | 2707 |
| 2692 void InstX8632Ret::emit(const Cfg *Func) const { | 2708 void InstX8632Ret::emit(const Cfg *Func) const { |
| 2693 if (!ALLOW_DUMP) | 2709 if (!ALLOW_DUMP) |
| 2694 return; | 2710 return; |
| 2695 Ostream &Str = Func->getContext()->getStrEmit(); | 2711 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2696 Str << "\tret"; | 2712 Str << "\tret"; |
| 2697 } | 2713 } |
| 2698 | 2714 |
| 2699 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 2715 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
| 2700 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2716 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2701 Asm->ret(); | 2717 Asm->ret(); |
| 2702 } | 2718 } |
| 2703 | 2719 |
| 2704 void InstX8632Ret::dump(const Cfg *Func) const { | 2720 void InstX8632Ret::dump(const Cfg *Func) const { |
| 2705 if (!ALLOW_DUMP) | 2721 if (!ALLOW_DUMP) |
| 2706 return; | 2722 return; |
| 2707 Ostream &Str = Func->getContext()->getStrDump(); | 2723 Ostream &Str = Func->getContext()->getStrDump(); |
| 2708 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 2724 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
| 2709 Str << "ret." << Ty << " "; | 2725 Str << "ret." << Ty << " "; |
| 2710 dumpSources(Func); | 2726 dumpSources(Func); |
| 2711 } | 2727 } |
| 2712 | 2728 |
| 2713 void InstX8632Xadd::emit(const Cfg *Func) const { | 2729 void InstX8632Xadd::emit(const Cfg *Func) const { |
| 2714 if (!ALLOW_DUMP) | 2730 if (!ALLOW_DUMP) |
| 2715 return; | 2731 return; |
| 2716 Ostream &Str = Func->getContext()->getStrEmit(); | 2732 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2717 if (Locked) { | 2733 if (Locked) { |
| 2718 Str << "\tlock"; | 2734 Str << "\tlock"; |
| 2719 } | 2735 } |
| 2720 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; | 2736 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 2721 getSrc(1)->emit(Func); | 2737 getSrc(1)->emit(Func); |
| 2722 Str << ", "; | 2738 Str << ", "; |
| 2723 getSrc(0)->emit(Func); | 2739 getSrc(0)->emit(Func); |
| 2724 } | 2740 } |
| 2725 | 2741 |
| 2726 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2742 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
| 2727 assert(getSrcSize() == 2); | 2743 assert(getSrcSize() == 2); |
| 2728 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2744 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2729 Type Ty = getSrc(0)->getType(); | 2745 Type Ty = getSrc(0)->getType(); |
| 2730 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2746 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2731 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2747 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2732 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2748 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
| 2733 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2749 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2734 assert(VarReg->hasReg()); | 2750 assert(VarReg->hasReg()); |
| 2735 const RegX8632::GPRRegister Reg = | 2751 const RegX8632::GPRRegister Reg = |
| 2736 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2752 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2737 Asm->xadd(Ty, Addr, Reg, Locked); | 2753 Asm->xadd(Ty, Addr, Reg, Locked); |
| 2738 } | 2754 } |
| 2739 | 2755 |
| 2740 void InstX8632Xadd::dump(const Cfg *Func) const { | 2756 void InstX8632Xadd::dump(const Cfg *Func) const { |
| 2741 if (!ALLOW_DUMP) | 2757 if (!ALLOW_DUMP) |
| 2742 return; | 2758 return; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2754 return; | 2770 return; |
| 2755 Ostream &Str = Func->getContext()->getStrEmit(); | 2771 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2756 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 2772 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 2757 getSrc(1)->emit(Func); | 2773 getSrc(1)->emit(Func); |
| 2758 Str << ", "; | 2774 Str << ", "; |
| 2759 getSrc(0)->emit(Func); | 2775 getSrc(0)->emit(Func); |
| 2760 } | 2776 } |
| 2761 | 2777 |
| 2762 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2778 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
| 2763 assert(getSrcSize() == 2); | 2779 assert(getSrcSize() == 2); |
| 2764 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2780 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2765 Type Ty = getSrc(0)->getType(); | 2781 Type Ty = getSrc(0)->getType(); |
| 2766 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2782 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2767 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2783 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2768 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2784 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
| 2769 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2785 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2770 assert(VarReg->hasReg()); | 2786 assert(VarReg->hasReg()); |
| 2771 const RegX8632::GPRRegister Reg = | 2787 const RegX8632::GPRRegister Reg = |
| 2772 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2788 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2773 Asm->xchg(Ty, Addr, Reg); | 2789 Asm->xchg(Ty, Addr, Reg); |
| 2774 } | 2790 } |
| 2775 | 2791 |
| 2776 void InstX8632Xchg::dump(const Cfg *Func) const { | 2792 void InstX8632Xchg::dump(const Cfg *Func) const { |
| 2777 if (!ALLOW_DUMP) | 2793 if (!ALLOW_DUMP) |
| 2778 return; | 2794 return; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2862 Str << "+"; | 2878 Str << "+"; |
| 2863 Offset->dump(Func, Str); | 2879 Offset->dump(Func, Str); |
| 2864 } | 2880 } |
| 2865 } else { | 2881 } else { |
| 2866 // There is only the offset. | 2882 // There is only the offset. |
| 2867 Offset->dump(Func, Str); | 2883 Offset->dump(Func, Str); |
| 2868 } | 2884 } |
| 2869 Str << "]"; | 2885 Str << "]"; |
| 2870 } | 2886 } |
| 2871 | 2887 |
| 2872 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const { | 2888 void OperandX8632Mem::emitSegmentOverride(X8632::AssemblerX8632 *Asm) const { |
| 2873 if (SegmentReg != DefaultSegment) { | 2889 if (SegmentReg != DefaultSegment) { |
| 2874 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 2890 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
| 2875 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); | 2891 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); |
| 2876 } | 2892 } |
| 2877 } | 2893 } |
| 2878 | 2894 |
| 2879 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { | 2895 X8632::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { |
| 2880 int32_t Disp = 0; | 2896 int32_t Disp = 0; |
| 2881 AssemblerFixup *Fixup = nullptr; | 2897 AssemblerFixup *Fixup = nullptr; |
| 2882 // Determine the offset (is it relocatable?) | 2898 // Determine the offset (is it relocatable?) |
| 2883 if (getOffset()) { | 2899 if (getOffset()) { |
| 2884 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 2900 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| 2885 Disp = static_cast<int32_t>(CI->getValue()); | 2901 Disp = static_cast<int32_t>(CI->getValue()); |
| 2886 } else if (const auto CR = | 2902 } else if (const auto CR = |
| 2887 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 2903 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| 2888 Disp = CR->getOffset(); | 2904 Disp = CR->getOffset(); |
| 2889 Fixup = Asm->createFixup(llvm::ELF::R_386_32, CR); | 2905 Fixup = Asm->createFixup(llvm::ELF::R_386_32, CR); |
| 2890 } else { | 2906 } else { |
| 2891 llvm_unreachable("Unexpected offset type"); | 2907 llvm_unreachable("Unexpected offset type"); |
| 2892 } | 2908 } |
| 2893 } | 2909 } |
| 2894 | 2910 |
| 2895 // Now convert to the various possible forms. | 2911 // Now convert to the various possible forms. |
| 2896 if (getBase() && getIndex()) { | 2912 if (getBase() && getIndex()) { |
| 2897 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), | 2913 return X8632::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
| 2898 RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2914 RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 2899 x86::ScaleFactor(getShift()), Disp); | 2915 X8632::ScaleFactor(getShift()), Disp); |
| 2900 } else if (getBase()) { | 2916 } else if (getBase()) { |
| 2901 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); | 2917 return X8632::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
| 2918 Disp); |
| 2902 } else if (getIndex()) { | 2919 } else if (getIndex()) { |
| 2903 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2920 return X8632::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 2904 x86::ScaleFactor(getShift()), Disp); | 2921 X8632::ScaleFactor(getShift()), Disp); |
| 2905 } else if (Fixup) { | 2922 } else if (Fixup) { |
| 2906 return x86::Address::Absolute(Disp, Fixup); | 2923 return X8632::Address::Absolute(Disp, Fixup); |
| 2907 } else { | 2924 } else { |
| 2908 return x86::Address::Absolute(Disp); | 2925 return X8632::Address::Absolute(Disp); |
| 2909 } | 2926 } |
| 2910 } | 2927 } |
| 2911 | 2928 |
| 2912 x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const { | 2929 X8632::Address VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 2913 assert(!Var->hasReg()); | 2930 assert(!Var->hasReg()); |
| 2914 const TargetLowering *Target = Func->getTarget(); | 2931 const TargetLowering *Target = Func->getTarget(); |
| 2915 int32_t Offset = | 2932 int32_t Offset = |
| 2916 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 2933 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 2917 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), | 2934 return X8632::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), |
| 2918 Offset); | 2935 Offset); |
| 2919 } | 2936 } |
| 2920 | 2937 |
| 2921 void VariableSplit::emit(const Cfg *Func) const { | 2938 void VariableSplit::emit(const Cfg *Func) const { |
| 2922 if (!ALLOW_DUMP) | 2939 if (!ALLOW_DUMP) |
| 2923 return; | 2940 return; |
| 2924 Ostream &Str = Func->getContext()->getStrEmit(); | 2941 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2925 assert(!Var->hasReg()); | 2942 assert(!Var->hasReg()); |
| 2926 // The following is copied/adapted from TargetX8632::emitVariable(). | 2943 // The following is copied/adapted from TargetX8632::emitVariable(). |
| 2927 const TargetLowering *Target = Func->getTarget(); | 2944 const TargetLowering *Target = Func->getTarget(); |
| 2928 const Type Ty = IceType_i32; | 2945 const Type Ty = IceType_i32; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2946 } | 2963 } |
| 2947 Str << "("; | 2964 Str << "("; |
| 2948 if (Func) | 2965 if (Func) |
| 2949 Var->dump(Func); | 2966 Var->dump(Func); |
| 2950 else | 2967 else |
| 2951 Var->dump(Str); | 2968 Var->dump(Str); |
| 2952 Str << ")"; | 2969 Str << ")"; |
| 2953 } | 2970 } |
| 2954 | 2971 |
| 2955 } // end of namespace Ice | 2972 } // end of namespace Ice |
| OLD | NEW |