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

Side by Side Diff: src/IceInstX8632.cpp

Issue 647193003: emitIAS for store and indirect calls. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: stuff Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 440
441 void InstX8632Call::emit(const Cfg *Func) const { 441 void InstX8632Call::emit(const Cfg *Func) const {
442 Ostream &Str = Func->getContext()->getStrEmit(); 442 Ostream &Str = Func->getContext()->getStrEmit();
443 assert(getSrcSize() == 1); 443 assert(getSrcSize() == 1);
444 Str << "\tcall\t"; 444 Str << "\tcall\t";
445 getCallTarget()->emit(Func); 445 getCallTarget()->emit(Func);
446 Str << "\n"; 446 Str << "\n";
447 Func->getTarget()->resetStackAdjustment(); 447 Func->getTarget()->resetStackAdjustment();
448 } 448 }
449 449
450 void InstX8632Call::emitIAS(const Cfg *Func) const {
451 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
452 intptr_t StartPosition = Asm->GetPosition();
453 Operand *Target = getCallTarget();
454 bool NeedsFallback = false;
455 if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
456 if (Var->hasReg()) {
457 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum()));
458 } else {
459 Asm->call(static_cast<TargetX8632 *>(Func->getTarget())
460 ->stackVarToAsmOperand(Var));
461 }
462 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) {
463 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
464 Asm->call(Mem->toAsmAddress(Asm));
465 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
466 assert(CR->getOffset() == 0 && "We only support calling a function");
Jim Stichnoth 2014/10/16 02:48:16 llvm_unreachable here too?
jvoung (off chromium) 2014/10/16 15:22:11 Oh, this one is actually reachable. I let it go th
467 Asm->call(CR);
468 NeedsFallback = true;
469 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
470 // NaCl trampoline calls refer to an address within the sandbox directly.
471 // This is usually only needed for non-IRT builds and otherwise not
472 // very portable or stable. For this, we would use the 0xE8 opcode
473 // (relative version of call) and there should be a PC32 reloc too.
474 // The PC32 reloc will have symbol index 0, and the absolute address
475 // would be encoded as an offset relative to the next instruction.
476 // TODO(jvoung): Do we need to support this?
477 (void)Imm;
478 llvm_unreachable("Unexpected call to absolute address");
479 } else {
480 llvm_unreachable("Unexpected operand type");
481 }
482 if (NeedsFallback) {
483 // TODO(jvoung): The ".long sym" hack doesn't work, since we need
484 // a pc-rel relocation and not an absolute relocation.
485 //
486 // Still, we have at least filled the assembler buffer so that the
487 // instruction sizes/positions are correct for jumps.
488 // For now, fall back to the regular .s emission, after filling the buffer.
489 emit(Func);
490 } else {
491 emitIASBytes(Func, Asm, StartPosition);
492 }
493 Func->getTarget()->resetStackAdjustment();
494 }
495
450 void InstX8632Call::dump(const Cfg *Func) const { 496 void InstX8632Call::dump(const Cfg *Func) const {
451 Ostream &Str = Func->getContext()->getStrDump(); 497 Ostream &Str = Func->getContext()->getStrDump();
452 if (getDest()) { 498 if (getDest()) {
453 dumpDest(Func); 499 dumpDest(Func);
454 Str << " = "; 500 Str << " = ";
455 } 501 }
456 Str << "call "; 502 Str << "call ";
457 getCallTarget()->dump(Func); 503 getCallTarget()->dump(Func);
458 } 504 }
459 505
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 578 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
533 Mem->emitSegmentOverride(Asm); 579 Mem->emitSegmentOverride(Asm);
534 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); 580 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
535 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { 581 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
536 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); 582 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
537 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { 583 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
538 AssemblerFixup *Fixup = 584 AssemblerFixup *Fixup =
539 x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc); 585 x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
540 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Fixup)); 586 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Fixup));
541 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { 587 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) {
542 x86::Address SrcAddr = Split->toAsmAddress(Func); 588 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
543 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcAddr);
544 } else { 589 } else {
545 llvm_unreachable("Unexpected operand type"); 590 llvm_unreachable("Unexpected operand type");
546 } 591 }
547 emitIASBytes(Func, Asm, StartPosition); 592 emitIASBytes(Func, Asm, StartPosition);
548 } 593 }
549 594
550 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, 595 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr,
551 const Operand *Src, 596 const Operand *Src,
552 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { 597 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) {
553 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 598 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
554 intptr_t StartPosition = Asm->GetPosition(); 599 intptr_t StartPosition = Asm->GetPosition();
555 // Src can only be Reg or Immediate. 600 // Src can only be Reg or Immediate.
556 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 601 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
557 assert(SrcVar->hasReg()); 602 assert(SrcVar->hasReg());
558 RegX8632::GPRRegister SrcReg = 603 RegX8632::GPRRegister SrcReg =
559 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); 604 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
560 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); 605 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
561 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { 606 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
562 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); 607 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue()));
563 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { 608 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
564 AssemblerFixup *Fixup = 609 AssemblerFixup *Fixup =
565 x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc); 610 x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
566 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Fixup)); 611 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Fixup));
567 } else { 612 } else {
568 llvm_unreachable("Unexpected operand type"); 613 llvm_unreachable("Unexpected operand type");
569 } 614 }
570 emitIASBytes(Func, Asm, StartPosition); 615 emitIASBytes(Func, Asm, StartPosition);
571 } 616 }
572 617
618 void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0,
619 const Operand *Op1,
620 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) {
621 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) {
622 assert(!Op0Var->hasReg());
623 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
624 ->stackVarToAsmOperand(Op0Var));
625 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter);
626 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) {
627 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
628 Op0Mem->emitSegmentOverride(Asm);
629 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter);
630 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) {
631 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter);
632 } else {
633 llvm_unreachable("Unexpected operand type");
634 }
635 }
636
573 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 637 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
574 const Operand *Src, 638 const Operand *Src,
575 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { 639 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) {
576 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 640 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
577 intptr_t StartPosition = Asm->GetPosition(); 641 intptr_t StartPosition = Asm->GetPosition();
578 // Technically, the Dest Var can be mem as well, but we only use Reg. 642 // Technically, the Dest Var can be mem as well, but we only use Reg.
579 // We can extend this to check Dest if we decide to use that form. 643 // We can extend this to check Dest if we decide to use that form.
580 assert(Var->hasReg()); 644 assert(Var->hasReg());
581 // We cheat a little and use GPRRegister even for byte operations. 645 // We cheat a little and use GPRRegister even for byte operations.
582 RegX8632::GPRRegister VarReg = 646 RegX8632::GPRRegister VarReg =
(...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 assert(getSrcSize() == 2); 1719 assert(getSrcSize() == 2);
1656 const Operand *Src0 = getSrc(0); 1720 const Operand *Src0 = getSrc(0);
1657 const Operand *Src1 = getSrc(1); 1721 const Operand *Src1 = getSrc(1);
1658 Type Ty = Src0->getType(); 1722 Type Ty = Src0->getType();
1659 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { 1723 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
1660 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp 1724 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp
1661 }; 1725 };
1662 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { 1726 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = {
1663 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp 1727 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp
1664 }; 1728 };
1665 if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { 1729 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
1666 if (SrcVar0->hasReg()) { 1730 if (SrcVar0->hasReg()) {
1667 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); 1731 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
1668 } else { 1732 return;
1669 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1670 ->stackVarToAsmOperand(SrcVar0));
1671 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter);
1672 } 1733 }
1673 } else if (const OperandX8632Mem *SrcMem0 =
1674 llvm::dyn_cast<OperandX8632Mem>(Src0)) {
1675 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1676 SrcMem0->emitSegmentOverride(Asm);
1677 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter);
1678 } 1734 }
1735 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter);
1679 } 1736 }
1680 1737
1681 void InstX8632Icmp::dump(const Cfg *Func) const { 1738 void InstX8632Icmp::dump(const Cfg *Func) const {
1682 Ostream &Str = Func->getContext()->getStrDump(); 1739 Ostream &Str = Func->getContext()->getStrDump();
1683 Str << "cmp." << getSrc(0)->getType() << " "; 1740 Str << "cmp." << getSrc(0)->getType() << " ";
1684 dumpSources(Func); 1741 dumpSources(Func);
1685 } 1742 }
1686 1743
1687 void InstX8632Ucomiss::emit(const Cfg *Func) const { 1744 void InstX8632Ucomiss::emit(const Cfg *Func) const {
1688 Ostream &Str = Func->getContext()->getStrEmit(); 1745 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 const Operand *Src0 = getSrc(0); 1804 const Operand *Src0 = getSrc(0);
1748 const Operand *Src1 = getSrc(1); 1805 const Operand *Src1 = getSrc(1);
1749 Type Ty = Src0->getType(); 1806 Type Ty = Src0->getType();
1750 // The Reg/Addr form of test is not encodeable. 1807 // The Reg/Addr form of test is not encodeable.
1751 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { 1808 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
1752 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test 1809 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test
1753 }; 1810 };
1754 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { 1811 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = {
1755 &x86::AssemblerX86::test, &x86::AssemblerX86::test 1812 &x86::AssemblerX86::test, &x86::AssemblerX86::test
1756 }; 1813 };
1757 if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { 1814 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
1758 if (SrcVar0->hasReg()) { 1815 if (SrcVar0->hasReg()) {
1759 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); 1816 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
1760 } else { 1817 return;
1761 llvm_unreachable("Nothing actually generates this so it's untested");
1762 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1763 ->stackVarToAsmOperand(SrcVar0));
1764 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter);
1765 } 1818 }
1766 } else if (const OperandX8632Mem *SrcMem0 =
1767 llvm::dyn_cast<OperandX8632Mem>(Src0)) {
1768 llvm_unreachable("Nothing actually generates this so it's untested");
1769 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1770 SrcMem0->emitSegmentOverride(Asm);
1771 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter);
1772 } 1819 }
1820 llvm_unreachable("Nothing actually generates this so it's untested");
1821 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter);
1773 } 1822 }
1774 1823
1775 void InstX8632Test::dump(const Cfg *Func) const { 1824 void InstX8632Test::dump(const Cfg *Func) const {
1776 Ostream &Str = Func->getContext()->getStrDump(); 1825 Ostream &Str = Func->getContext()->getStrDump();
1777 Str << "test." << getSrc(0)->getType() << " "; 1826 Str << "test." << getSrc(0)->getType() << " ";
1778 dumpSources(Func); 1827 dumpSources(Func);
1779 } 1828 }
1780 1829
1781 void InstX8632Mfence::emit(const Cfg *Func) const { 1830 void InstX8632Mfence::emit(const Cfg *Func) const {
1782 Ostream &Str = Func->getContext()->getStrEmit(); 1831 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 17 matching lines...) Expand all
1800 Ostream &Str = Func->getContext()->getStrEmit(); 1849 Ostream &Str = Func->getContext()->getStrEmit();
1801 assert(getSrcSize() == 2); 1850 assert(getSrcSize() == 2);
1802 Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString 1851 Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString
1803 << "\t"; 1852 << "\t";
1804 getSrc(1)->emit(Func); 1853 getSrc(1)->emit(Func);
1805 Str << ", "; 1854 Str << ", ";
1806 getSrc(0)->emit(Func); 1855 getSrc(0)->emit(Func);
1807 Str << "\n"; 1856 Str << "\n";
1808 } 1857 }
1809 1858
1859 void InstX8632Store::emitIAS(const Cfg *Func) const {
1860 assert(getSrcSize() == 2);
1861 const Operand *Dest = getSrc(1);
1862 const Operand *Src = getSrc(0);
1863 Type DestTy = Dest->getType();
1864 if (isScalarFloatingType(DestTy)) {
1865 // Src must be a register, since Dest is a Mem operand of some kind.
1866 const Variable *SrcVar = llvm::cast<Variable>(Src);
1867 assert(SrcVar->hasReg());
1868 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum());
1869 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1870 intptr_t StartPosition = Asm->GetPosition();
1871 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
1872 assert(!DestVar->hasReg());
1873 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1874 ->stackVarToAsmOperand(DestVar));
1875 Asm->movss(DestTy, StackAddr, SrcReg);
1876 } else {
1877 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest);
1878 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1879 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg);
1880 }
1881 emitIASBytes(Func, Asm, StartPosition);
1882 return;
1883 } else {
1884 assert(isScalarIntegerType(DestTy));
1885 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = {
1886 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov};
1887 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter);
1888 }
1889 }
1890
1810 void InstX8632Store::dump(const Cfg *Func) const { 1891 void InstX8632Store::dump(const Cfg *Func) const {
1811 Ostream &Str = Func->getContext()->getStrDump(); 1892 Ostream &Str = Func->getContext()->getStrDump();
1812 Str << "mov." << getSrc(0)->getType() << " "; 1893 Str << "mov." << getSrc(0)->getType() << " ";
1813 getSrc(1)->dump(Func); 1894 getSrc(1)->dump(Func);
1814 Str << ", "; 1895 Str << ", ";
1815 getSrc(0)->dump(Func); 1896 getSrc(0)->dump(Func);
1816 } 1897 }
1817 1898
1818 void InstX8632StoreP::emit(const Cfg *Func) const { 1899 void InstX8632StoreP::emit(const Cfg *Func) const {
1819 Ostream &Str = Func->getContext()->getStrEmit(); 1900 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after
2795 } 2876 }
2796 Str << "("; 2877 Str << "(";
2797 if (Func) 2878 if (Func)
2798 Var->dump(Func); 2879 Var->dump(Func);
2799 else 2880 else
2800 Var->dump(Str); 2881 Var->dump(Str);
2801 Str << ")"; 2882 Str << ")";
2802 } 2883 }
2803 2884
2804 } // end of namespace Ice 2885 } // end of namespace Ice
OLDNEW
« src/IceInst.h ('K') | « src/IceInstX8632.h ('k') | src/assembler_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698