diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-02-21 13:51:43 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-02-21 13:51:43 +0000 |
| commit | 3f4bde29a30d8c43db5cbe8f5541ebc5d1fdc6af (patch) | |
| tree | 87140683fc3fee4e14b3c37e2aa7a4031d473f49 /lib/Target/X86 | |
| parent | a322a4af1fe8b989fe5d1bbc15de8736a26c03ca (diff) | |
Notes
Diffstat (limited to 'lib/Target/X86')
| -rw-r--r-- | lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 46 | ||||
| -rw-r--r-- | lib/Target/X86/X86FrameLowering.cpp | 13 | ||||
| -rw-r--r-- | lib/Target/X86/X86InstrAVX512.td | 2 |
3 files changed, 21 insertions, 40 deletions
diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 133bd0e1772a..135c32bf8c3b 100644 --- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -69,19 +69,15 @@ public: class X86AsmBackend : public MCAsmBackend { const StringRef CPU; bool HasNopl; - uint64_t MaxNopLength; + const uint64_t MaxNopLength; public: - X86AsmBackend(const Target &T, StringRef CPU) : MCAsmBackend(), CPU(CPU) { + X86AsmBackend(const Target &T, StringRef CPU) + : MCAsmBackend(), CPU(CPU), MaxNopLength(CPU == "slm" ? 7 : 15) { HasNopl = CPU != "generic" && CPU != "i386" && CPU != "i486" && CPU != "i586" && CPU != "pentium" && CPU != "pentium-mmx" && CPU != "i686" && CPU != "k6" && CPU != "k6-2" && CPU != "k6-3" && CPU != "geode" && CPU != "winchip-c6" && CPU != "winchip2" && CPU != "c3" && CPU != "c3-2"; - // Max length of true long nop instruction is 15 bytes. - // Max length of long nop replacement instruction is 7 bytes. - // Taking into account SilverMont architecture features max length of nops - // is reduced for it to achieve better performance. - MaxNopLength = (!HasNopl || CPU == "slm") ? 7 : 15; } unsigned getNumFixupKinds() const override { @@ -299,7 +295,7 @@ void X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { /// bytes. /// \return - true on success, false on failure bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { - static const uint8_t TrueNops[10][10] = { + static const uint8_t Nops[10][10] = { // nop {0x90}, // xchg %ax,%ax @@ -322,31 +318,17 @@ bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, }; - // Alternative nop instructions for CPUs which don't support long nops. - static const uint8_t AltNops[7][10] = { - // nop - {0x90}, - // xchg %ax,%ax - {0x66, 0x90}, - // lea 0x0(%esi),%esi - {0x8d, 0x76, 0x00}, - // lea 0x0(%esi),%esi - {0x8d, 0x74, 0x26, 0x00}, - // nop + lea 0x0(%esi),%esi - {0x90, 0x8d, 0x74, 0x26, 0x00}, - // lea 0x0(%esi),%esi - {0x8d, 0xb6, 0x00, 0x00, 0x00, 0x00 }, - // lea 0x0(%esi),%esi - {0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00}, - }; - - // Select the right NOP table. - // FIXME: Can we get if CPU supports long nops from the subtarget somehow? - const uint8_t (*Nops)[10] = HasNopl ? TrueNops : AltNops; - assert(HasNopl || MaxNopLength <= 7); + // This CPU doesn't support long nops. If needed add more. + // FIXME: Can we get this from the subtarget somehow? + // FIXME: We could generated something better than plain 0x90. + if (!HasNopl) { + for (uint64_t i = 0; i < Count; ++i) + OW->write8(0x90); + return true; + } - // Emit as many largest nops as needed, then emit a nop of the remaining - // length. + // 15 is the longest single nop instruction. Emit as many 15-byte nops as + // needed, then emit a nop of the remaining length. do { const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength); const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10; diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 7f8ce4768c00..f5ffe0cf7e88 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -192,10 +192,9 @@ static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, return 0; } -static bool isEAXLiveIn(MachineFunction &MF) { - for (MachineRegisterInfo::livein_iterator II = MF.getRegInfo().livein_begin(), - EE = MF.getRegInfo().livein_end(); II != EE; ++II) { - unsigned Reg = II->first; +static bool isEAXLiveIn(MachineBasicBlock &MBB) { + for (MachineBasicBlock::RegisterMaskPair RegMask : MBB.liveins()) { + unsigned Reg = RegMask.PhysReg; if (Reg == X86::RAX || Reg == X86::EAX || Reg == X86::AX || Reg == X86::AH || Reg == X86::AL) @@ -261,7 +260,7 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB, // load the offset into a register and do one sub/add unsigned Reg = 0; - if (isSub && !isEAXLiveIn(*MBB.getParent())) + if (isSub && !isEAXLiveIn(MBB)) Reg = (unsigned)(Is64Bit ? X86::RAX : X86::EAX); else Reg = findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit); @@ -1133,8 +1132,8 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, if (IsWin64Prologue && !IsFunclet && TRI->needsStackRealignment(MF)) AlignedNumBytes = RoundUpToAlignment(AlignedNumBytes, MaxAlign); if (AlignedNumBytes >= StackProbeSize && UseStackProbe) { - // Check whether EAX is livein for this function. - bool isEAXAlive = isEAXLiveIn(MF); + // Check whether EAX is livein for this block. + bool isEAXAlive = isEAXLiveIn(MBB); if (isEAXAlive) { // Sanity check that EAX is not livein for this function. diff --git a/lib/Target/X86/X86InstrAVX512.td b/lib/Target/X86/X86InstrAVX512.td index 49be64883939..6f0199b015cd 100644 --- a/lib/Target/X86/X86InstrAVX512.td +++ b/lib/Target/X86/X86InstrAVX512.td @@ -5896,7 +5896,7 @@ multiclass avx512_sqrt_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _, def : Pat<(_.EltVT (OpNode (load addr:$src))), (!cast<Instruction>(NAME#SUFF#Zm) - (_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[OptForSize]>; + (_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[HasAVX512, OptForSize]>; } multiclass avx512_sqrt_scalar_all<bits<8> opc, string OpcodeStr> { |
