diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-03-21 10:49:05 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-03-21 10:49:05 +0000 |
commit | 2f2afc1aae898651e26987a5c71f3febb19bca98 (patch) | |
tree | 2caca31db4facdc95c23930c0c745c8ef0dee97d /lib/Target/X86 | |
parent | 0f448b841684305c051796982f300c9bff959307 (diff) | |
download | FreeBSD-src-2f2afc1aae898651e26987a5c71f3febb19bca98.zip FreeBSD-src-2f2afc1aae898651e26987a5c71f3febb19bca98.tar.gz |
Update LLVM to r99115.
Diffstat (limited to 'lib/Target/X86')
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 49 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86MCInstLower.cpp | 2 | ||||
-rw-r--r-- | lib/Target/X86/Disassembler/X86Disassembler.cpp | 4 | ||||
-rw-r--r-- | lib/Target/X86/Disassembler/X86DisassemblerDecoder.c | 4 | ||||
-rw-r--r-- | lib/Target/X86/X86.td | 1 | ||||
-rw-r--r-- | lib/Target/X86/X86AsmBackend.cpp | 75 | ||||
-rw-r--r-- | lib/Target/X86/X86FastISel.cpp | 15 | ||||
-rw-r--r-- | lib/Target/X86/X86FixupKinds.h | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 74 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 22 | ||||
-rw-r--r-- | lib/Target/X86/X86Instr64bit.td | 173 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrFPStack.td | 10 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 347 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrSSE.td | 93 | ||||
-rw-r--r-- | lib/Target/X86/X86MCCodeEmitter.cpp | 28 | ||||
-rw-r--r-- | lib/Target/X86/X86Subtarget.cpp | 9 | ||||
-rw-r--r-- | lib/Target/X86/X86Subtarget.h | 6 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetMachine.cpp | 2 |
18 files changed, 401 insertions, 516 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index dde86fb..47873d1 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -29,6 +29,9 @@ struct X86Operand; class X86ATTAsmParser : public TargetAsmParser { MCAsmParser &Parser; +protected: + unsigned Is64Bit : 1; + private: MCAsmParser &getParser() const { return Parser; } @@ -45,6 +48,8 @@ private: bool ParseDirectiveWord(unsigned Size, SMLoc L); + void InstructionCleanup(MCInst &Inst); + /// @name Auto-generated Match Functions /// { @@ -62,7 +67,23 @@ public: virtual bool ParseDirective(AsmToken DirectiveID); }; - + +class X86_32ATTAsmParser : public X86ATTAsmParser { +public: + X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser) + : X86ATTAsmParser(T, _Parser) { + Is64Bit = false; + } +}; + +class X86_64ATTAsmParser : public X86ATTAsmParser { +public: + X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser) + : X86ATTAsmParser(T, _Parser) { + Is64Bit = true; + } +}; + } // end anonymous namespace /// @name Auto-generated Match Functions @@ -548,8 +569,10 @@ ParseInstruction(const StringRef &Name, SMLoc NameLoc, Operands.size() == 3 && static_cast<X86Operand*>(Operands[1])->isImm() && isa<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm()) && - cast<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm())->getValue() == 1) + cast<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm())->getValue() == 1) { + delete Operands[1]; Operands.erase(Operands.begin() + 1); + } return false; } @@ -586,12 +609,30 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { return false; } +// FIXME: Custom X86 cleanup function to implement a temporary hack to handle +// matching INCL/DECL correctly for x86_64. This needs to be replaced by a +// proper mechanism for supporting (ambiguous) feature dependent instructions. +void X86ATTAsmParser::InstructionCleanup(MCInst &Inst) { + if (!Is64Bit) return; + + switch (Inst.getOpcode()) { + case X86::DEC16r: Inst.setOpcode(X86::DEC64_16r); break; + case X86::DEC16m: Inst.setOpcode(X86::DEC64_16m); break; + case X86::DEC32r: Inst.setOpcode(X86::DEC64_32r); break; + case X86::DEC32m: Inst.setOpcode(X86::DEC64_32m); break; + case X86::INC16r: Inst.setOpcode(X86::INC64_16r); break; + case X86::INC16m: Inst.setOpcode(X86::INC64_16m); break; + case X86::INC32r: Inst.setOpcode(X86::INC64_32r); break; + case X86::INC32m: Inst.setOpcode(X86::INC64_32m); break; + } +} + extern "C" void LLVMInitializeX86AsmLexer(); // Force static initialization. extern "C" void LLVMInitializeX86AsmParser() { - RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target); - RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target); + RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target); + RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target); LLVMInitializeX86AsmLexer(); } diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp index cbfc57a..7d29d97 100644 --- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp +++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp @@ -427,7 +427,7 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { // MYGLOBAL + (. - PICBASE) // However, we can't generate a ".", so just emit a new label here and refer // to it. - MCSymbol *DotSym = OutContext.GetOrCreateTemporarySymbol(); + MCSymbol *DotSym = OutContext.CreateTempSymbol(); OutStreamer.EmitLabel(DotSym); // Now that we have emitted the label, lower the complex operand expression. diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp index a316860..7b7b5cb 100644 --- a/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -459,11 +459,11 @@ static void translateInstruction(MCInst &mcInst, } } -static const MCDisassembler *createX86_32Disassembler(const Target &T) { +static MCDisassembler *createX86_32Disassembler(const Target &T) { return new X86Disassembler::X86_32Disassembler; } -static const MCDisassembler *createX86_64Disassembler(const Target &T) { +static MCDisassembler *createX86_64Disassembler(const Target &T) { return new X86Disassembler::X86_64Disassembler; } diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index a0a04ba..4f02ed4 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -1355,8 +1355,8 @@ int decodeInstruction(struct InternalInstruction* insn, insn->length = insn->readerCursor - insn->startLocation; - dbgprintf(insn, "Read from 0x%llx to 0x%llx: length %llu", - startLoc, insn->readerCursor, insn->length); + dbgprintf(insn, "Read from 0x%llx to 0x%llx: length %zu", + startLoc, insn->readerCursor, insn->length); if (insn->length > 15) dbgprintf(insn, "Instruction exceeds 15-byte limit"); diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index 6a4bdb5..2be51e1 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -191,6 +191,7 @@ include "X86CallingConv.td" // Currently the X86 assembly parser only supports ATT syntax. def ATTAsmParser : AsmParser { string AsmParserClassName = "ATTAsmParser"; + string AsmParserInstCleanup = "InstructionCleanup"; int Variant = 0; // Discard comments in assembly strings. diff --git a/lib/Target/X86/X86AsmBackend.cpp b/lib/Target/X86/X86AsmBackend.cpp index a44afc6..754a200 100644 --- a/lib/Target/X86/X86AsmBackend.cpp +++ b/lib/Target/X86/X86AsmBackend.cpp @@ -9,39 +9,100 @@ #include "llvm/Target/TargetAsmBackend.h" #include "X86.h" +#include "X86FixupKinds.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MachObjectWriter.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetAsmBackend.h" using namespace llvm; namespace { +static unsigned getFixupKindLog2Size(unsigned Kind) { + switch (Kind) { + default: assert(0 && "invalid fixup kind!"); + case X86::reloc_pcrel_1byte: + case FK_Data_1: return 0; + case FK_Data_2: return 1; + case X86::reloc_pcrel_4byte: + case X86::reloc_riprel_4byte: + case X86::reloc_riprel_4byte_movq_load: + case FK_Data_4: return 2; + case FK_Data_8: return 3; + } +} + class X86AsmBackend : public TargetAsmBackend { public: X86AsmBackend(const Target &T) : TargetAsmBackend(T) {} + + void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF, + uint64_t Value) const { + unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind); + + assert(Fixup.Offset + Size <= DF.getContents().size() && + "Invalid fixup offset!"); + for (unsigned i = 0; i != Size; ++i) + DF.getContents()[Fixup.Offset + i] = uint8_t(Value >> (i * 8)); + } +}; + +class ELFX86AsmBackend : public X86AsmBackend { +public: + ELFX86AsmBackend(const Target &T) + : X86AsmBackend(T) { + HasAbsolutizedSet = true; + HasScatteredSymbols = true; + } + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + return 0; + } + + bool isVirtualSection(const MCSection &Section) const { + const MCSectionELF &SE = static_cast<const MCSectionELF&>(Section); + return SE.getType() == MCSectionELF::SHT_NOBITS;; + } }; class DarwinX86AsmBackend : public X86AsmBackend { public: DarwinX86AsmBackend(const Target &T) - : X86AsmBackend(T) {} - - virtual bool hasAbsolutizedSet() const { return true; } + : X86AsmBackend(T) { + HasAbsolutizedSet = true; + HasScatteredSymbols = true; + } - virtual bool hasScatteredSymbols() const { return true; } + bool isVirtualSection(const MCSection &Section) const { + const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); + return (SMO.getType() == MCSectionMachO::S_ZEROFILL || + SMO.getType() == MCSectionMachO::S_GB_ZEROFILL); + } }; class DarwinX86_32AsmBackend : public DarwinX86AsmBackend { public: DarwinX86_32AsmBackend(const Target &T) : DarwinX86AsmBackend(T) {} + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + return new MachObjectWriter(OS, /*Is64Bit=*/false); + } }; class DarwinX86_64AsmBackend : public DarwinX86AsmBackend { public: DarwinX86_64AsmBackend(const Target &T) - : DarwinX86AsmBackend(T) {} + : DarwinX86AsmBackend(T) { + HasReliableSymbolDifference = true; + } + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + return new MachObjectWriter(OS, /*Is64Bit=*/true); + } virtual bool doesSectionRequireSymbols(const MCSection &Section) const { // Temporary labels in the string literals sections require symbols. The @@ -65,7 +126,7 @@ TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T, case Triple::Darwin: return new DarwinX86_32AsmBackend(T); default: - return new X86AsmBackend(T); + return new ELFX86AsmBackend(T); } } @@ -75,6 +136,6 @@ TargetAsmBackend *llvm::createX86_64AsmBackend(const Target &T, case Triple::Darwin: return new DarwinX86_64AsmBackend(T); default: - return new X86AsmBackend(T); + return new ELFX86AsmBackend(T); } } diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 96b652d..5d3edbb 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -1166,6 +1166,21 @@ bool X86FastISel::X86VisitIntrinsicCall(IntrinsicInst &I) { // FIXME: Handle more intrinsics. switch (I.getIntrinsicID()) { default: return false; + case Intrinsic::stackprotector: { + // Emit code inline code to store the stack guard onto the stack. + EVT PtrTy = TLI.getPointerTy(); + + Value *Op1 = I.getOperand(1); // The guard's value. + AllocaInst *Slot = cast<AllocaInst>(I.getOperand(2)); + + // Grab the frame index. + X86AddressMode AM; + if (!X86SelectAddress(Slot, AM)) return false; + + if (!X86FastEmitStore(PtrTy, Op1, AM)) return false; + + return true; + } case Intrinsic::objectsize: { ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(2)); const Type *Ty = I.getCalledFunction()->getReturnType(); diff --git a/lib/Target/X86/X86FixupKinds.h b/lib/Target/X86/X86FixupKinds.h index c8dac3c..a8117d4 100644 --- a/lib/Target/X86/X86FixupKinds.h +++ b/lib/Target/X86/X86FixupKinds.h @@ -17,7 +17,8 @@ namespace X86 { enum Fixups { reloc_pcrel_4byte = FirstTargetFixupKind, // 32-bit pcrel, e.g. a branch. reloc_pcrel_1byte, // 8-bit pcrel, e.g. branch_1 - reloc_riprel_4byte // 32-bit rip-relative + reloc_riprel_4byte, // 32-bit rip-relative + reloc_riprel_4byte_movq_load // 32-bit rip-relative in movq }; } } diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 4058885..1c0ed7e 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -140,6 +140,21 @@ namespace { } namespace { + class X86ISelListener : public SelectionDAG::DAGUpdateListener { + SmallSet<SDNode*, 4> Deletes; + public: + explicit X86ISelListener() {} + virtual void NodeDeleted(SDNode *N, SDNode *E) { + Deletes.insert(N); + } + virtual void NodeUpdated(SDNode *N) { + // Ignore updates. + } + bool IsDeleted(SDNode *N) { + return Deletes.count(N); + } + }; + //===--------------------------------------------------------------------===// /// ISel - X86 specific code to select X86 machine instructions for /// SelectionDAG operations. @@ -187,6 +202,7 @@ namespace { bool MatchWrapper(SDValue N, X86ISelAddressMode &AM); bool MatchAddress(SDValue N, X86ISelAddressMode &AM); bool MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, + X86ISelListener &DeadNodes, unsigned Depth); bool MatchAddressBase(SDValue N, X86ISelAddressMode &AM); bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, @@ -651,7 +667,8 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) { /// returning true if it cannot be done. This just pattern matches for the /// addressing mode. bool X86DAGToDAGISel::MatchAddress(SDValue N, X86ISelAddressMode &AM) { - if (MatchAddressRecursively(N, AM, 0)) + X86ISelListener DeadNodes; + if (MatchAddressRecursively(N, AM, DeadNodes, 0)) return true; // Post-processing: Convert lea(,%reg,2) to lea(%reg,%reg), which has @@ -680,6 +697,7 @@ bool X86DAGToDAGISel::MatchAddress(SDValue N, X86ISelAddressMode &AM) { } bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, + X86ISelListener &DeadNodes, unsigned Depth) { bool is64Bit = Subtarget->is64Bit(); DebugLoc dl = N.getDebugLoc(); @@ -845,7 +863,11 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, // Test if the LHS of the sub can be folded. X86ISelAddressMode Backup = AM; - if (MatchAddressRecursively(N.getNode()->getOperand(0), AM, Depth+1)) { + if (MatchAddressRecursively(N.getNode()->getOperand(0), AM, + DeadNodes, Depth+1) || + // If it is successful but the recursive update causes N to be deleted, + // then it's not safe to continue. + DeadNodes.IsDeleted(N.getNode())) { AM = Backup; break; } @@ -854,6 +876,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, AM = Backup; break; } + int Cost = 0; SDValue RHS = N.getNode()->getOperand(1); // If the RHS involves a register with multiple uses, this @@ -907,13 +930,33 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, case ISD::ADD: { X86ISelAddressMode Backup = AM; - if (!MatchAddressRecursively(N.getNode()->getOperand(0), AM, Depth+1) && - !MatchAddressRecursively(N.getNode()->getOperand(1), AM, Depth+1)) - return false; + if (!MatchAddressRecursively(N.getNode()->getOperand(0), AM, + DeadNodes, Depth+1)) { + if (DeadNodes.IsDeleted(N.getNode())) + // If it is successful but the recursive update causes N to be deleted, + // then it's not safe to continue. + return true; + if (!MatchAddressRecursively(N.getNode()->getOperand(1), AM, + DeadNodes, Depth+1)) + // If it is successful but the recursive update causes N to be deleted, + // then it's not safe to continue. + return DeadNodes.IsDeleted(N.getNode()); + } + + // Try again after commuting the operands. AM = Backup; - if (!MatchAddressRecursively(N.getNode()->getOperand(1), AM, Depth+1) && - !MatchAddressRecursively(N.getNode()->getOperand(0), AM, Depth+1)) - return false; + if (!MatchAddressRecursively(N.getNode()->getOperand(1), AM, + DeadNodes, Depth+1)) { + if (DeadNodes.IsDeleted(N.getNode())) + // If it is successful but the recursive update causes N to be deleted, + // then it's not safe to continue. + return true; + if (!MatchAddressRecursively(N.getNode()->getOperand(0), AM, + DeadNodes, Depth+1)) + // If it is successful but the recursive update causes N to be deleted, + // then it's not safe to continue. + return DeadNodes.IsDeleted(N.getNode()); + } AM = Backup; // If we couldn't fold both operands into the address at the same time, @@ -935,16 +978,19 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) { X86ISelAddressMode Backup = AM; uint64_t Offset = CN->getSExtValue(); + + // Check to see if the LHS & C is zero. + if (!CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) + break; + // Start with the LHS as an addr mode. - if (!MatchAddressRecursively(N.getOperand(0), AM, Depth+1) && + if (!MatchAddressRecursively(N.getOperand(0), AM, DeadNodes, Depth+1) && // Address could not have picked a GV address for the displacement. AM.GV == NULL && // On x86-64, the resultant disp must fit in 32-bits. (!is64Bit || X86::isOffsetSuitableForCodeModel(AM.Disp + Offset, M, - AM.hasSymbolicDisplacement())) && - // Check to see if the LHS & C is zero. - CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) { + AM.hasSymbolicDisplacement()))) { AM.Disp += Offset; return false; } @@ -1015,7 +1061,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, CurDAG->RepositionNode(N.getNode(), Shl.getNode()); Shl.getNode()->setNodeId(N.getNode()->getNodeId()); } - CurDAG->ReplaceAllUsesWith(N, Shl); + CurDAG->ReplaceAllUsesWith(N, Shl, &DeadNodes); AM.IndexReg = And; AM.Scale = (1 << ScaleLog); return false; @@ -1066,7 +1112,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, NewSHIFT.getNode()->setNodeId(N.getNode()->getNodeId()); } - CurDAG->ReplaceAllUsesWith(N, NewSHIFT); + CurDAG->ReplaceAllUsesWith(N, NewSHIFT, &DeadNodes); AM.Scale = 1 << ShiftCst; AM.IndexReg = NewAND; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 7d2140b..704f9c6 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2310,6 +2310,28 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, if (isCalleeStructRet || isCallerStructRet) return false; + // If the call result is in ST0 / ST1, it needs to be popped off the x87 stack. + // Therefore if it's not used by the call it is not safe to optimize this into + // a sibcall. + bool Unused = false; + for (unsigned i = 0, e = Ins.size(); i != e; ++i) { + if (!Ins[i].Used) { + Unused = true; + break; + } + } + if (Unused) { + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CalleeCC, false, getTargetMachine(), + RVLocs, *DAG.getContext()); + CCInfo.AnalyzeCallResult(Ins, RetCC_X86); + for (unsigned i = 0; i != RVLocs.size(); ++i) { + CCValAssign &VA = RVLocs[i]; + if (VA.getLocReg() == X86::ST0 || VA.getLocReg() == X86::ST1) + return false; + } + } + // If the callee takes no arguments then go on to check the results of the // call. if (!Outs.empty()) { diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index 4262c0ac..8cbb756 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -144,7 +144,7 @@ let isCall = 1 in // NOTE: this pattern doesn't match "X86call imm", because we do not know // that the offset between an arbitrary immediate and the call will fit in // the 32-bit pcrel field that we have. - def CALL64pcrel32 : Ii32<0xE8, RawFrm, + def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm, (outs), (ins i64i32imm_pcrel:$dst, variable_ops), "call{q}\t$dst", []>, Requires<[In64BitMode, NotWin64]>; @@ -511,6 +511,14 @@ def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), [(set GR64:$dst, (add GR64:$src1, GR64:$src2)), (implicit EFLAGS)]>; +// These are alternate spellings for use by the disassembler, we mark them as +// code gen only to ensure they aren't matched by the assembler. +let isCodeGenOnly = 1 in { + def ADD64rr_alt : RI<0x03, MRMSrcReg, (outs GR64:$dst), + (ins GR64:$src1, GR64:$src2), + "add{l}\t{$src2, $dst|$dst, $src2}", []>; +} + // Register-Integer Addition def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), @@ -531,12 +539,6 @@ def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), [(set GR64:$dst, (add GR64:$src1, (load addr:$src2))), (implicit EFLAGS)]>; -// Register-Register Addition - Equivalent to the normal rr form (ADD64rr), but -// differently encoded. -def ADD64mrmrr : RI<0x03, MRMSrcReg, (outs GR64:$dst), - (ins GR64:$src1, GR64:$src2), - "add{l}\t{$src2, $dst|$dst, $src2}", []>; - } // isTwoAddress // Memory-Register Addition @@ -1225,59 +1227,59 @@ let Defs = [EFLAGS] in { def TEST64i32 : RIi32<0xa9, RawFrm, (outs), (ins i32imm:$src), "test{q}\t{$src, %rax|%rax, $src}", []>; let isCommutable = 1 in -def TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), +def TEST64rr : RI<0x85, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2), "test{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR64:$src1, GR64:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and GR64:$src1, GR64:$src2), 0))]>; def TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), "test{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and GR64:$src1, (loadi64 addr:$src2)), + 0))]>; def TEST64ri32 : RIi32<0xF7, MRM0r, (outs), (ins GR64:$src1, i64i32imm:$src2), "test{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and GR64:$src1, i64immSExt32:$src2), + 0))]>; def TEST64mi32 : RIi32<0xF7, MRM0m, (outs), (ins i64mem:$src1, i64i32imm:$src2), "test{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and (loadi64 addr:$src1), + i64immSExt32:$src2), 0))]>; def CMP64i32 : RIi32<0x3D, RawFrm, (outs), (ins i32imm:$src), "cmp{q}\t{$src, %rax|%rax, $src}", []>; def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR64:$src1, GR64:$src2), - (implicit EFLAGS)]>; -def CMP64mrmrr : RI<0x3B, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", []>; + [(set EFLAGS, (X86cmp GR64:$src1, GR64:$src2))]>; + +// These are alternate spellings for use by the disassembler, we mark them as +// code gen only to ensure they aren't matched by the assembler. +let isCodeGenOnly = 1 in { + def CMP64mrmrr : RI<0x3B, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2), + "cmp{q}\t{$src2, $src1|$src1, $src2}", []>; +} + def CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi64 addr:$src1), GR64:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (loadi64 addr:$src1), GR64:$src2))]>; def CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR64:$src1, (loadi64 addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR64:$src1, (loadi64 addr:$src2)))]>; def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2), "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR64:$src1, i64immSExt8:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR64:$src1, i64immSExt8:$src2))]>; def CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2), "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR64:$src1, i64immSExt32:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR64:$src1, i64immSExt32:$src2))]>; def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2), "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi64 addr:$src1), i64immSExt8:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (loadi64 addr:$src1), + i64immSExt8:$src2))]>; def CMP64mi32 : RIi32<0x81, MRM7m, (outs), (ins i64mem:$src1, i64i32imm:$src2), "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi64 addr:$src1), i64immSExt32:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (loadi64 addr:$src1), + i64immSExt32:$src2))]>; } // Defs = [EFLAGS] // Bit tests. @@ -1285,8 +1287,7 @@ def CMP64mi32 : RIi32<0x81, MRM7m, (outs), let Defs = [EFLAGS] in { def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), "bt{q}\t{$src2, $src1|$src1, $src2}", - [(X86bt GR64:$src1, GR64:$src2), - (implicit EFLAGS)]>, TB; + [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB; // Unlike with the register+register form, the memory+register form of the // bt instruction does not ignore the high bits of the index. From ISel's @@ -1300,15 +1301,14 @@ def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), def BT64ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2), "bt{q}\t{$src2, $src1|$src1, $src2}", - [(X86bt GR64:$src1, i64immSExt8:$src2), - (implicit EFLAGS)]>, TB; + [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))]>, TB; // Note that these instructions don't need FastBTMem because that // only applies when the other operand is in a register. When it's // an immediate, bt is still fast. def BT64mi8 : Ii8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2), "bt{q}\t{$src2, $src1|$src1, $src2}", - [(X86bt (loadi64 addr:$src1), i64immSExt8:$src2), - (implicit EFLAGS)]>, TB; + [(set EFLAGS, (X86bt (loadi64 addr:$src1), + i64immSExt8:$src2))]>, TB; def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB; @@ -1938,7 +1938,7 @@ def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off), // Comparisons. // TEST R,R is smaller than CMP R,0 -def : Pat<(parallel (X86cmp GR64:$src1, 0), (implicit EFLAGS)), +def : Pat<(X86cmp GR64:$src1, 0), (TEST64rr GR64:$src1, GR64:$src1)>; // Conditional moves with folded loads with operands swapped and conditions @@ -2233,21 +2233,6 @@ def : Pat<(parallel (X86add_flag GR64:$src1, (loadi64 addr:$src2)), (implicit EFLAGS)), (ADD64rm GR64:$src1, addr:$src2)>; -// Memory-Register Addition with EFLAGS result -def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), GR64:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD64mr addr:$dst, GR64:$src2)>; -def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD64mi8 addr:$dst, i64immSExt8:$src2)>; -def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), - i64immSExt32:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD64mi32 addr:$dst, i64immSExt32:$src2)>; - // Register-Register Subtraction with EFLAGS result def : Pat<(parallel (X86sub_flag GR64:$src1, GR64:$src2), (implicit EFLAGS)), @@ -2266,24 +2251,6 @@ def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt32:$src2), (implicit EFLAGS)), (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>; -// Memory-Register Subtraction with EFLAGS result -def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), GR64:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB64mr addr:$dst, GR64:$src2)>; - -// Memory-Integer Subtraction with EFLAGS result -def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), - i64immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB64mi8 addr:$dst, i64immSExt8:$src2)>; -def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), - i64immSExt32:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB64mi32 addr:$dst, i64immSExt32:$src2)>; - // Register-Register Signed Integer Multiplication with EFLAGS result def : Pat<(parallel (X86smul_flag GR64:$src1, GR64:$src2), (implicit EFLAGS)), @@ -2313,36 +2280,18 @@ def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt32:$src2), // INC and DEC with EFLAGS result. Note that these do not set CF. def : Pat<(parallel (X86inc_flag GR16:$src), (implicit EFLAGS)), (INC64_16r GR16:$src)>, Requires<[In64BitMode]>; -def : Pat<(parallel (store (i16 (X86inc_flag (loadi16 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (INC64_16m addr:$dst)>, Requires<[In64BitMode]>; def : Pat<(parallel (X86dec_flag GR16:$src), (implicit EFLAGS)), (DEC64_16r GR16:$src)>, Requires<[In64BitMode]>; -def : Pat<(parallel (store (i16 (X86dec_flag (loadi16 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (DEC64_16m addr:$dst)>, Requires<[In64BitMode]>; def : Pat<(parallel (X86inc_flag GR32:$src), (implicit EFLAGS)), (INC64_32r GR32:$src)>, Requires<[In64BitMode]>; -def : Pat<(parallel (store (i32 (X86inc_flag (loadi32 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (INC64_32m addr:$dst)>, Requires<[In64BitMode]>; def : Pat<(parallel (X86dec_flag GR32:$src), (implicit EFLAGS)), (DEC64_32r GR32:$src)>, Requires<[In64BitMode]>; -def : Pat<(parallel (store (i32 (X86dec_flag (loadi32 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (DEC64_32m addr:$dst)>, Requires<[In64BitMode]>; def : Pat<(parallel (X86inc_flag GR64:$src), (implicit EFLAGS)), (INC64r GR64:$src)>; -def : Pat<(parallel (store (i64 (X86inc_flag (loadi64 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (INC64m addr:$dst)>; def : Pat<(parallel (X86dec_flag GR64:$src), (implicit EFLAGS)), (DEC64r GR64:$src)>; -def : Pat<(parallel (store (i64 (X86dec_flag (loadi64 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (DEC64m addr:$dst)>; // Register-Register Logical Or with EFLAGS result def : Pat<(parallel (X86or_flag GR64:$src1, GR64:$src2), @@ -2362,20 +2311,6 @@ def : Pat<(parallel (X86or_flag GR64:$src1, (loadi64 addr:$src2)), (implicit EFLAGS)), (OR64rm GR64:$src1, addr:$src2)>; -// Memory-Register Logical Or with EFLAGS result -def : Pat<(parallel (store (X86or_flag (loadi64 addr:$dst), GR64:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR64mr addr:$dst, GR64:$src2)>; -def : Pat<(parallel (store (X86or_flag (loadi64 addr:$dst), i64immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR64mi8 addr:$dst, i64immSExt8:$src2)>; -def : Pat<(parallel (store (X86or_flag (loadi64 addr:$dst), i64immSExt32:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR64mi32 addr:$dst, i64immSExt32:$src2)>; - // Register-Register Logical XOr with EFLAGS result def : Pat<(parallel (X86xor_flag GR64:$src1, GR64:$src2), (implicit EFLAGS)), @@ -2394,21 +2329,6 @@ def : Pat<(parallel (X86xor_flag GR64:$src1, (loadi64 addr:$src2)), (implicit EFLAGS)), (XOR64rm GR64:$src1, addr:$src2)>; -// Memory-Register Logical XOr with EFLAGS result -def : Pat<(parallel (store (X86xor_flag (loadi64 addr:$dst), GR64:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR64mr addr:$dst, GR64:$src2)>; -def : Pat<(parallel (store (X86xor_flag (loadi64 addr:$dst), i64immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR64mi8 addr:$dst, i64immSExt8:$src2)>; -def : Pat<(parallel (store (X86xor_flag (loadi64 addr:$dst), - i64immSExt32:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR64mi32 addr:$dst, i64immSExt32:$src2)>; - // Register-Register Logical And with EFLAGS result def : Pat<(parallel (X86and_flag GR64:$src1, GR64:$src2), (implicit EFLAGS)), @@ -2427,21 +2347,6 @@ def : Pat<(parallel (X86and_flag GR64:$src1, (loadi64 addr:$src2)), (implicit EFLAGS)), (AND64rm GR64:$src1, addr:$src2)>; -// Memory-Register Logical And with EFLAGS result -def : Pat<(parallel (store (X86and_flag (loadi64 addr:$dst), GR64:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND64mr addr:$dst, GR64:$src2)>; -def : Pat<(parallel (store (X86and_flag (loadi64 addr:$dst), i64immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND64mi8 addr:$dst, i64immSExt8:$src2)>; -def : Pat<(parallel (store (X86and_flag (loadi64 addr:$dst), - i64immSExt32:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND64mi32 addr:$dst, i64immSExt32:$src2)>; - //===----------------------------------------------------------------------===// // X86-64 SSE Instructions //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td index b730918..e6d1fee 100644 --- a/lib/Target/X86/X86InstrFPStack.td +++ b/lib/Target/X86/X86InstrFPStack.td @@ -562,15 +562,13 @@ def UCOM_Fpr64 : FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, def UCOM_Fpr80 : FpI_ <(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, []>; // FPSW = cmp ST(0) with ST(i) +// CC = ST(0) cmp ST(i) def UCOM_FpIr32: FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, - [(X86cmp RFP32:$lhs, RFP32:$rhs), - (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) + [(set EFLAGS, (X86cmp RFP32:$lhs, RFP32:$rhs))]>; def UCOM_FpIr64: FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, - [(X86cmp RFP64:$lhs, RFP64:$rhs), - (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) + [(set EFLAGS, (X86cmp RFP64:$lhs, RFP64:$rhs))]>; def UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, - [(X86cmp RFP80:$lhs, RFP80:$rhs), - (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) + [(set EFLAGS, (X86cmp RFP80:$lhs, RFP80:$rhs))]>; } let Defs = [EFLAGS], Uses = [ST0] in { diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 1225b68..c80a18d 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -21,8 +21,7 @@ def SDTIntShiftDOp: SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3>]>; -// FIXME: Should be modelled as returning i32 -def SDTX86CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; +def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisSameAs<1, 2>]>; def SDTX86Cmov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, @@ -120,12 +119,12 @@ def X86AtomSwap64 : SDNode<"X86ISD::ATOMSWAP64_DAG", SDTX86atomicBinary, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>; def X86vastart_save_xmm_regs : SDNode<"X86ISD::VASTART_SAVE_XMM_REGS", SDT_X86VASTART_SAVE_XMM_REGS, - [SDNPHasChain]>; + [SDNPHasChain, SDNPVariadic]>; def X86callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart, @@ -135,7 +134,8 @@ def X86callseq_end : [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def X86call : SDNode<"X86ISD::CALL", SDT_X86Call, - [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag, + SDNPVariadic]>; def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr, [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore]>; @@ -158,7 +158,7 @@ def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET, [SDNPHasChain]>; def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>; def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags, [SDNPCommutative]>; @@ -661,9 +661,9 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { // Loop instructions -def LOOP : I<0xE2, RawFrm, (ins brtarget8:$dst), (outs), "loop\t$dst", []>; -def LOOPE : I<0xE1, RawFrm, (ins brtarget8:$dst), (outs), "loope\t$dst", []>; -def LOOPNE : I<0xE0, RawFrm, (ins brtarget8:$dst), (outs), "loopne\t$dst", []>; +def LOOP : I<0xE2, RawFrm, (outs), (ins brtarget8:$dst), "loop\t$dst", []>; +def LOOPE : I<0xE1, RawFrm, (outs), (ins brtarget8:$dst), "loope\t$dst", []>; +def LOOPNE : I<0xE0, RawFrm, (outs), (ins brtarget8:$dst), "loopne\t$dst", []>; //===----------------------------------------------------------------------===// // Call Instructions... @@ -3200,17 +3200,16 @@ let Defs = [EFLAGS] in { let isCommutable = 1 in { // TEST X, Y --> TEST Y, X def TEST8rr : I<0x84, MRMSrcReg, (outs), (ins GR8:$src1, GR8:$src2), "test{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and_su GR8:$src1, GR8:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and_su GR8:$src1, GR8:$src2), 0))]>; def TEST16rr : I<0x85, MRMSrcReg, (outs), (ins GR16:$src1, GR16:$src2), "test{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and_su GR16:$src1, GR16:$src2), 0), - (implicit EFLAGS)]>, + [(set EFLAGS, (X86cmp (and_su GR16:$src1, GR16:$src2), + 0))]>, OpSize; def TEST32rr : I<0x85, MRMSrcReg, (outs), (ins GR32:$src1, GR32:$src2), "test{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and_su GR32:$src1, GR32:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and_su GR32:$src1, GR32:$src2), + 0))]>; } def TEST8i8 : Ii8<0xA8, RawFrm, (outs), (ins i8imm:$src), @@ -3222,48 +3221,46 @@ def TEST32i32 : Ii32<0xA9, RawFrm, (outs), (ins i32imm:$src), def TEST8rm : I<0x84, MRMSrcMem, (outs), (ins GR8 :$src1, i8mem :$src2), "test{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR8:$src1, (loadi8 addr:$src2)), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and GR8:$src1, (loadi8 addr:$src2)), + 0))]>; def TEST16rm : I<0x85, MRMSrcMem, (outs), (ins GR16:$src1, i16mem:$src2), "test{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR16:$src1, (loadi16 addr:$src2)), 0), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp (and GR16:$src1, + (loadi16 addr:$src2)), 0))]>, OpSize; def TEST32rm : I<0x85, MRMSrcMem, (outs), (ins GR32:$src1, i32mem:$src2), "test{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR32:$src1, (loadi32 addr:$src2)), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and GR32:$src1, + (loadi32 addr:$src2)), 0))]>; def TEST8ri : Ii8 <0xF6, MRM0r, // flags = GR8 & imm8 (outs), (ins GR8:$src1, i8imm:$src2), "test{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and_su GR8:$src1, imm:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and_su GR8:$src1, imm:$src2), 0))]>; def TEST16ri : Ii16<0xF7, MRM0r, // flags = GR16 & imm16 (outs), (ins GR16:$src1, i16imm:$src2), "test{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and_su GR16:$src1, imm:$src2), 0), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp (and_su GR16:$src1, imm:$src2), 0))]>, + OpSize; def TEST32ri : Ii32<0xF7, MRM0r, // flags = GR32 & imm32 (outs), (ins GR32:$src1, i32imm:$src2), "test{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and_su GR32:$src1, imm:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and_su GR32:$src1, imm:$src2), 0))]>; def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8 (outs), (ins i8mem:$src1, i8imm:$src2), "test{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and (loadi8 addr:$src1), imm:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and (loadi8 addr:$src1), imm:$src2), + 0))]>; def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16 (outs), (ins i16mem:$src1, i16imm:$src2), "test{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and (loadi16 addr:$src1), imm:$src2), 0), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp (and (loadi16 addr:$src1), imm:$src2), + 0))]>, OpSize; def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32 (outs), (ins i32mem:$src1, i32imm:$src2), "test{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and (loadi32 addr:$src1), imm:$src2), 0), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (and (loadi32 addr:$src1), imm:$src2), + 0))]>; } // Defs = [EFLAGS] @@ -3477,45 +3474,41 @@ def CMP32i32 : Ii32<0x3D, RawFrm, (outs), (ins i32imm:$src), def CMP8rr : I<0x38, MRMDestReg, (outs), (ins GR8 :$src1, GR8 :$src2), "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR8:$src1, GR8:$src2), (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR8:$src1, GR8:$src2))]>; def CMP16rr : I<0x39, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2), "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR16:$src1, GR16:$src2), (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp GR16:$src1, GR16:$src2))]>, OpSize; def CMP32rr : I<0x39, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2), "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR32:$src1, GR32:$src2), (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR32:$src1, GR32:$src2))]>; def CMP8mr : I<0x38, MRMDestMem, (outs), (ins i8mem :$src1, GR8 :$src2), "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi8 addr:$src1), GR8:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (loadi8 addr:$src1), GR8:$src2))]>; def CMP16mr : I<0x39, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi16 addr:$src1), GR16:$src2), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp (loadi16 addr:$src1), GR16:$src2))]>, + OpSize; def CMP32mr : I<0x39, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi32 addr:$src1), GR32:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (loadi32 addr:$src1), GR32:$src2))]>; def CMP8rm : I<0x3A, MRMSrcMem, (outs), (ins GR8 :$src1, i8mem :$src2), "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR8:$src1, (loadi8 addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR8:$src1, (loadi8 addr:$src2)))]>; def CMP16rm : I<0x3B, MRMSrcMem, (outs), (ins GR16:$src1, i16mem:$src2), "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR16:$src1, (loadi16 addr:$src2)), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp GR16:$src1, (loadi16 addr:$src2)))]>, + OpSize; def CMP32rm : I<0x3B, MRMSrcMem, (outs), (ins GR32:$src1, i32mem:$src2), "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR32:$src1, (loadi32 addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR32:$src1, (loadi32 addr:$src2)))]>; // These are alternate spellings for use by the disassembler, we mark them as // code gen only to ensure they aren't matched by the assembler. @@ -3531,51 +3524,47 @@ let isCodeGenOnly = 1 in { def CMP8ri : Ii8<0x80, MRM7r, (outs), (ins GR8:$src1, i8imm:$src2), "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR8:$src1, imm:$src2), (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR8:$src1, imm:$src2))]>; def CMP16ri : Ii16<0x81, MRM7r, (outs), (ins GR16:$src1, i16imm:$src2), "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR16:$src1, imm:$src2), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp GR16:$src1, imm:$src2))]>, OpSize; def CMP32ri : Ii32<0x81, MRM7r, (outs), (ins GR32:$src1, i32imm:$src2), "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR32:$src1, imm:$src2), (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR32:$src1, imm:$src2))]>; def CMP8mi : Ii8 <0x80, MRM7m, (outs), (ins i8mem :$src1, i8imm :$src2), "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi8 addr:$src1), imm:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (loadi8 addr:$src1), imm:$src2))]>; def CMP16mi : Ii16<0x81, MRM7m, (outs), (ins i16mem:$src1, i16imm:$src2), "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi16 addr:$src1), imm:$src2), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp (loadi16 addr:$src1), imm:$src2))]>, + OpSize; def CMP32mi : Ii32<0x81, MRM7m, (outs), (ins i32mem:$src1, i32imm:$src2), "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi32 addr:$src1), imm:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (loadi32 addr:$src1), imm:$src2))]>; def CMP16ri8 : Ii8<0x83, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2), "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR16:$src1, i16immSExt8:$src2), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp GR16:$src1, i16immSExt8:$src2))]>, + OpSize; def CMP16mi8 : Ii8<0x83, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2), "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi16 addr:$src1), i16immSExt8:$src2), - (implicit EFLAGS)]>, OpSize; + [(set EFLAGS, (X86cmp (loadi16 addr:$src1), + i16immSExt8:$src2))]>, OpSize; def CMP32mi8 : Ii8<0x83, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2), "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi32 addr:$src1), i32immSExt8:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp (loadi32 addr:$src1), + i32immSExt8:$src2))]>; def CMP32ri8 : Ii8<0x83, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2), "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR32:$src1, i32immSExt8:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp GR32:$src1, i32immSExt8:$src2))]>; } // Defs = [EFLAGS] // Bit tests. @@ -3583,12 +3572,10 @@ def CMP32ri8 : Ii8<0x83, MRM7r, let Defs = [EFLAGS] in { def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2), "bt{w}\t{$src2, $src1|$src1, $src2}", - [(X86bt GR16:$src1, GR16:$src2), - (implicit EFLAGS)]>, OpSize, TB; + [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>, OpSize, TB; def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2), "bt{l}\t{$src2, $src1|$src1, $src2}", - [(X86bt GR32:$src1, GR32:$src2), - (implicit EFLAGS)]>, TB; + [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>, TB; // Unlike with the register+register form, the memory+register form of the // bt instruction does not ignore the high bits of the index. From ISel's @@ -3610,23 +3597,22 @@ def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2), "bt{w}\t{$src2, $src1|$src1, $src2}", - [(X86bt GR16:$src1, i16immSExt8:$src2), - (implicit EFLAGS)]>, OpSize, TB; + [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))]>, + OpSize, TB; def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2), "bt{l}\t{$src2, $src1|$src1, $src2}", - [(X86bt GR32:$src1, i32immSExt8:$src2), - (implicit EFLAGS)]>, TB; + [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))]>, TB; // Note that these instructions don't need FastBTMem because that // only applies when the other operand is in a register. When it's // an immediate, bt is still fast. def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2), "bt{w}\t{$src2, $src1|$src1, $src2}", - [(X86bt (loadi16 addr:$src1), i16immSExt8:$src2), - (implicit EFLAGS)]>, OpSize, TB; + [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2)) + ]>, OpSize, TB; def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2), "bt{l}\t{$src2, $src1|$src1, $src2}", - [(X86bt (loadi32 addr:$src1), i32immSExt8:$src2), - (implicit EFLAGS)]>, TB; + [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2)) + ]>, TB; def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2), "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize, TB; @@ -4401,11 +4387,11 @@ def : Pat<(subc GR32:$src1, i32immSExt8:$src2), // Comparisons. // TEST R,R is smaller than CMP R,0 -def : Pat<(parallel (X86cmp GR8:$src1, 0), (implicit EFLAGS)), +def : Pat<(X86cmp GR8:$src1, 0), (TEST8rr GR8:$src1, GR8:$src1)>; -def : Pat<(parallel (X86cmp GR16:$src1, 0), (implicit EFLAGS)), +def : Pat<(X86cmp GR16:$src1, 0), (TEST16rr GR16:$src1, GR16:$src1)>; -def : Pat<(parallel (X86cmp GR32:$src1, 0), (implicit EFLAGS)), +def : Pat<(X86cmp GR32:$src1, 0), (TEST32rr GR32:$src1, GR32:$src1)>; // Conditional moves with folded loads with operands swapped and conditions @@ -4799,42 +4785,6 @@ def : Pat<(parallel (X86add_flag GR32:$src1, i32immSExt8:$src2), (implicit EFLAGS)), (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>; -// Memory-Register Addition with EFLAGS result -def : Pat<(parallel (store (X86add_flag (loadi8 addr:$dst), GR8:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD8mr addr:$dst, GR8:$src2)>; -def : Pat<(parallel (store (X86add_flag (loadi16 addr:$dst), GR16:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD16mr addr:$dst, GR16:$src2)>; -def : Pat<(parallel (store (X86add_flag (loadi32 addr:$dst), GR32:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD32mr addr:$dst, GR32:$src2)>; - -// Memory-Integer Addition with EFLAGS result -def : Pat<(parallel (store (X86add_flag (loadi8 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD8mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86add_flag (loadi16 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD16mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86add_flag (loadi32 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD32mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86add_flag (loadi16 addr:$dst), i16immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD16mi8 addr:$dst, i16immSExt8:$src2)>; -def : Pat<(parallel (store (X86add_flag (loadi32 addr:$dst), i32immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (ADD32mi8 addr:$dst, i32immSExt8:$src2)>; - // Register-Register Subtraction with EFLAGS result def : Pat<(parallel (X86sub_flag GR8:$src1, GR8:$src2), (implicit EFLAGS)), @@ -4874,43 +4824,6 @@ def : Pat<(parallel (X86sub_flag GR32:$src1, i32immSExt8:$src2), (implicit EFLAGS)), (SUB32ri8 GR32:$src1, i32immSExt8:$src2)>; -// Memory-Register Subtraction with EFLAGS result -def : Pat<(parallel (store (X86sub_flag (loadi8 addr:$dst), GR8:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB8mr addr:$dst, GR8:$src2)>; -def : Pat<(parallel (store (X86sub_flag (loadi16 addr:$dst), GR16:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB16mr addr:$dst, GR16:$src2)>; -def : Pat<(parallel (store (X86sub_flag (loadi32 addr:$dst), GR32:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB32mr addr:$dst, GR32:$src2)>; - -// Memory-Integer Subtraction with EFLAGS result -def : Pat<(parallel (store (X86sub_flag (loadi8 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB8mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86sub_flag (loadi16 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB16mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86sub_flag (loadi32 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB32mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86sub_flag (loadi16 addr:$dst), i16immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB16mi8 addr:$dst, i16immSExt8:$src2)>; -def : Pat<(parallel (store (X86sub_flag (loadi32 addr:$dst), i32immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (SUB32mi8 addr:$dst, i32immSExt8:$src2)>; - - // Register-Register Signed Integer Multiply with EFLAGS result def : Pat<(parallel (X86smul_flag GR16:$src1, GR16:$src2), (implicit EFLAGS)), @@ -4969,36 +4882,18 @@ def : Pat<(parallel (X86smul_flag GR32:$src1, 2), // INC and DEC with EFLAGS result. Note that these do not set CF. def : Pat<(parallel (X86inc_flag GR8:$src), (implicit EFLAGS)), (INC8r GR8:$src)>; -def : Pat<(parallel (store (i8 (X86inc_flag (loadi8 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (INC8m addr:$dst)>; def : Pat<(parallel (X86dec_flag GR8:$src), (implicit EFLAGS)), (DEC8r GR8:$src)>; -def : Pat<(parallel (store (i8 (X86dec_flag (loadi8 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (DEC8m addr:$dst)>; def : Pat<(parallel (X86inc_flag GR16:$src), (implicit EFLAGS)), (INC16r GR16:$src)>, Requires<[In32BitMode]>; -def : Pat<(parallel (store (i16 (X86inc_flag (loadi16 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (INC16m addr:$dst)>, Requires<[In32BitMode]>; def : Pat<(parallel (X86dec_flag GR16:$src), (implicit EFLAGS)), (DEC16r GR16:$src)>, Requires<[In32BitMode]>; -def : Pat<(parallel (store (i16 (X86dec_flag (loadi16 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (DEC16m addr:$dst)>, Requires<[In32BitMode]>; def : Pat<(parallel (X86inc_flag GR32:$src), (implicit EFLAGS)), (INC32r GR32:$src)>, Requires<[In32BitMode]>; -def : Pat<(parallel (store (i32 (X86inc_flag (loadi32 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (INC32m addr:$dst)>, Requires<[In32BitMode]>; def : Pat<(parallel (X86dec_flag GR32:$src), (implicit EFLAGS)), (DEC32r GR32:$src)>, Requires<[In32BitMode]>; -def : Pat<(parallel (store (i32 (X86dec_flag (loadi32 addr:$dst))), addr:$dst), - (implicit EFLAGS)), - (DEC32m addr:$dst)>, Requires<[In32BitMode]>; // Register-Register Or with EFLAGS result def : Pat<(parallel (X86or_flag GR8:$src1, GR8:$src2), @@ -5039,42 +4934,6 @@ def : Pat<(parallel (X86or_flag GR32:$src1, i32immSExt8:$src2), (implicit EFLAGS)), (OR32ri8 GR32:$src1, i32immSExt8:$src2)>; -// Memory-Register Or with EFLAGS result -def : Pat<(parallel (store (X86or_flag (loadi8 addr:$dst), GR8:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR8mr addr:$dst, GR8:$src2)>; -def : Pat<(parallel (store (X86or_flag (loadi16 addr:$dst), GR16:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR16mr addr:$dst, GR16:$src2)>; -def : Pat<(parallel (store (X86or_flag (loadi32 addr:$dst), GR32:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR32mr addr:$dst, GR32:$src2)>; - -// Memory-Integer Or with EFLAGS result -def : Pat<(parallel (store (X86or_flag (loadi8 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR8mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86or_flag (loadi16 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR16mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86or_flag (loadi32 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR32mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86or_flag (loadi16 addr:$dst), i16immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR16mi8 addr:$dst, i16immSExt8:$src2)>; -def : Pat<(parallel (store (X86or_flag (loadi32 addr:$dst), i32immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (OR32mi8 addr:$dst, i32immSExt8:$src2)>; - // Register-Register XOr with EFLAGS result def : Pat<(parallel (X86xor_flag GR8:$src1, GR8:$src2), (implicit EFLAGS)), @@ -5114,42 +4973,6 @@ def : Pat<(parallel (X86xor_flag GR32:$src1, i32immSExt8:$src2), (implicit EFLAGS)), (XOR32ri8 GR32:$src1, i32immSExt8:$src2)>; -// Memory-Register XOr with EFLAGS result -def : Pat<(parallel (store (X86xor_flag (loadi8 addr:$dst), GR8:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR8mr addr:$dst, GR8:$src2)>; -def : Pat<(parallel (store (X86xor_flag (loadi16 addr:$dst), GR16:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR16mr addr:$dst, GR16:$src2)>; -def : Pat<(parallel (store (X86xor_flag (loadi32 addr:$dst), GR32:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR32mr addr:$dst, GR32:$src2)>; - -// Memory-Integer XOr with EFLAGS result -def : Pat<(parallel (store (X86xor_flag (loadi8 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR8mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86xor_flag (loadi16 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR16mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86xor_flag (loadi32 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR32mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86xor_flag (loadi16 addr:$dst), i16immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR16mi8 addr:$dst, i16immSExt8:$src2)>; -def : Pat<(parallel (store (X86xor_flag (loadi32 addr:$dst), i32immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (XOR32mi8 addr:$dst, i32immSExt8:$src2)>; - // Register-Register And with EFLAGS result def : Pat<(parallel (X86and_flag GR8:$src1, GR8:$src2), (implicit EFLAGS)), @@ -5189,42 +5012,6 @@ def : Pat<(parallel (X86and_flag GR32:$src1, i32immSExt8:$src2), (implicit EFLAGS)), (AND32ri8 GR32:$src1, i32immSExt8:$src2)>; -// Memory-Register And with EFLAGS result -def : Pat<(parallel (store (X86and_flag (loadi8 addr:$dst), GR8:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND8mr addr:$dst, GR8:$src2)>; -def : Pat<(parallel (store (X86and_flag (loadi16 addr:$dst), GR16:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND16mr addr:$dst, GR16:$src2)>; -def : Pat<(parallel (store (X86and_flag (loadi32 addr:$dst), GR32:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND32mr addr:$dst, GR32:$src2)>; - -// Memory-Integer And with EFLAGS result -def : Pat<(parallel (store (X86and_flag (loadi8 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND8mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86and_flag (loadi16 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND16mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86and_flag (loadi32 addr:$dst), imm:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND32mi addr:$dst, imm:$src2)>; -def : Pat<(parallel (store (X86and_flag (loadi16 addr:$dst), i16immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND16mi8 addr:$dst, i16immSExt8:$src2)>; -def : Pat<(parallel (store (X86and_flag (loadi32 addr:$dst), i32immSExt8:$src2), - addr:$dst), - (implicit EFLAGS)), - (AND32mi8 addr:$dst, i32immSExt8:$src2)>; - // -disable-16bit support. def : Pat<(truncstorei16 (i16 imm:$src), addr:$dst), (MOV16mi addr:$dst, imm:$src)>; diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index 18f9e52..720b663 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -513,11 +513,10 @@ let mayLoad = 1 in let Defs = [EFLAGS] in { def UCOMISSrr: PSI<0x2E, MRMSrcReg, (outs), (ins FR32:$src1, FR32:$src2), "ucomiss\t{$src2, $src1|$src1, $src2}", - [(X86cmp FR32:$src1, FR32:$src2), (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp FR32:$src1, FR32:$src2))]>; def UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs), (ins FR32:$src1, f32mem:$src2), "ucomiss\t{$src2, $src1|$src1, $src2}", - [(X86cmp FR32:$src1, (loadf32 addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp FR32:$src1, (loadf32 addr:$src2)))]>; def COMISSrr: PSI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), "comiss\t{$src2, $src1|$src1, $src2}", []>; @@ -546,21 +545,21 @@ let Constraints = "$src1 = $dst" in { let Defs = [EFLAGS] in { def Int_UCOMISSrr: PSI<0x2E, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), "ucomiss\t{$src2, $src1|$src1, $src2}", - [(X86ucomi (v4f32 VR128:$src1), VR128:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86ucomi (v4f32 VR128:$src1), + VR128:$src2))]>; def Int_UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs),(ins VR128:$src1, f128mem:$src2), "ucomiss\t{$src2, $src1|$src1, $src2}", - [(X86ucomi (v4f32 VR128:$src1), (load addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86ucomi (v4f32 VR128:$src1), + (load addr:$src2)))]>; def Int_COMISSrr: PSI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), "comiss\t{$src2, $src1|$src1, $src2}", - [(X86comi (v4f32 VR128:$src1), VR128:$src2), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86comi (v4f32 VR128:$src1), + VR128:$src2))]>; def Int_COMISSrm: PSI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2), "comiss\t{$src2, $src1|$src1, $src2}", - [(X86comi (v4f32 VR128:$src1), (load addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86comi (v4f32 VR128:$src1), + (load addr:$src2)))]>; } // Defs = [EFLAGS] // Aliases of packed SSE1 instructions for scalar use. These all have names @@ -1298,11 +1297,10 @@ let mayLoad = 1 in let Defs = [EFLAGS] in { def UCOMISDrr: PDI<0x2E, MRMSrcReg, (outs), (ins FR64:$src1, FR64:$src2), "ucomisd\t{$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, FR64:$src2), (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp FR64:$src1, FR64:$src2))]>; def UCOMISDrm: PDI<0x2E, MRMSrcMem, (outs), (ins FR64:$src1, f64mem:$src2), "ucomisd\t{$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, (loadf64 addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86cmp FR64:$src1, (loadf64 addr:$src2)))]>; } // Defs = [EFLAGS] // Aliases to match intrinsics which expect XMM operand(s). @@ -1324,21 +1322,21 @@ let Constraints = "$src1 = $dst" in { let Defs = [EFLAGS] in { def Int_UCOMISDrr: PDI<0x2E, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), "ucomisd\t{$src2, $src1|$src1, $src2}", - [(X86ucomi (v2f64 VR128:$src1), (v2f64 VR128:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86ucomi (v2f64 VR128:$src1), + VR128:$src2))]>; def Int_UCOMISDrm: PDI<0x2E, MRMSrcMem, (outs),(ins VR128:$src1, f128mem:$src2), "ucomisd\t{$src2, $src1|$src1, $src2}", - [(X86ucomi (v2f64 VR128:$src1), (load addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86ucomi (v2f64 VR128:$src1), + (load addr:$src2)))]>; def Int_COMISDrr: PDI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), "comisd\t{$src2, $src1|$src1, $src2}", - [(X86comi (v2f64 VR128:$src1), (v2f64 VR128:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86comi (v2f64 VR128:$src1), + VR128:$src2))]>; def Int_COMISDrm: PDI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2), "comisd\t{$src2, $src1|$src1, $src2}", - [(X86comi (v2f64 VR128:$src1), (load addr:$src2)), - (implicit EFLAGS)]>; + [(set EFLAGS, (X86comi (v2f64 VR128:$src1), + (load addr:$src2)))]>; } // Defs = [EFLAGS] // Aliases of packed SSE2 instructions for scalar use. These all have names @@ -3825,54 +3823,65 @@ def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))), let Constraints = "$src1 = $dst" in { def CRC32m8 : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i8mem:$src2), - "crc32 \t{$src2, $src1|$src1, $src2}", + "crc32{b} \t{$src2, $src1|$src1, $src2}", [(set GR32:$dst, (int_x86_sse42_crc32_8 GR32:$src1, - (load addr:$src2)))]>, OpSize; + (load addr:$src2)))]>; def CRC32r8 : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR8:$src2), - "crc32 \t{$src2, $src1|$src1, $src2}", + "crc32{b} \t{$src2, $src1|$src1, $src2}", [(set GR32:$dst, - (int_x86_sse42_crc32_8 GR32:$src1, GR8:$src2))]>, - OpSize; + (int_x86_sse42_crc32_8 GR32:$src1, GR8:$src2))]>; def CRC32m16 : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i16mem:$src2), - "crc32 \t{$src2, $src1|$src1, $src2}", + "crc32{w} \t{$src2, $src1|$src1, $src2}", [(set GR32:$dst, (int_x86_sse42_crc32_16 GR32:$src1, (load addr:$src2)))]>, OpSize; def CRC32r16 : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR16:$src2), - "crc32 \t{$src2, $src1|$src1, $src2}", + "crc32{w} \t{$src2, $src1|$src1, $src2}", [(set GR32:$dst, (int_x86_sse42_crc32_16 GR32:$src1, GR16:$src2))]>, OpSize; def CRC32m32 : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), - "crc32 \t{$src2, $src1|$src1, $src2}", + "crc32{l} \t{$src2, $src1|$src1, $src2}", [(set GR32:$dst, (int_x86_sse42_crc32_32 GR32:$src1, - (load addr:$src2)))]>, OpSize; + (load addr:$src2)))]>; def CRC32r32 : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), - "crc32 \t{$src2, $src1|$src1, $src2}", + "crc32{l} \t{$src2, $src1|$src1, $src2}", [(set GR32:$dst, - (int_x86_sse42_crc32_32 GR32:$src1, GR32:$src2))]>, - OpSize; - def CRC64m64 : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst), + (int_x86_sse42_crc32_32 GR32:$src1, GR32:$src2))]>; + def CRC64m8 : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst), + (ins GR64:$src1, i8mem:$src2), + "crc32{b} \t{$src2, $src1|$src1, $src2}", + [(set GR64:$dst, + (int_x86_sse42_crc64_8 GR64:$src1, + (load addr:$src2)))]>, + REX_W; + def CRC64r8 : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst), + (ins GR64:$src1, GR8:$src2), + "crc32{b} \t{$src2, $src1|$src1, $src2}", + [(set GR64:$dst, + (int_x86_sse42_crc64_8 GR64:$src1, GR8:$src2))]>, + REX_W; + def CRC64m64 : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "crc32 \t{$src2, $src1|$src1, $src2}", + "crc32{q} \t{$src2, $src1|$src1, $src2}", [(set GR64:$dst, - (int_x86_sse42_crc32_64 GR64:$src1, + (int_x86_sse42_crc64_64 GR64:$src1, (load addr:$src2)))]>, - OpSize, REX_W; - def CRC64r64 : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst), + REX_W; + def CRC64r64 : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "crc32 \t{$src2, $src1|$src1, $src2}", + "crc32{q} \t{$src2, $src1|$src1, $src2}", [(set GR64:$dst, - (int_x86_sse42_crc32_64 GR64:$src1, GR64:$src2))]>, - OpSize, REX_W; + (int_x86_sse42_crc64_64 GR64:$src1, GR64:$src2))]>, + REX_W; } // String/text processing instructions. diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp index 3f18696..a9681e6 100644 --- a/lib/Target/X86/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/X86MCCodeEmitter.cpp @@ -38,14 +38,15 @@ public: ~X86MCCodeEmitter() {} unsigned getNumFixupKinds() const { - return 3; + return 4; } const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[] = { - { "reloc_pcrel_4byte", 0, 4 * 8 }, - { "reloc_pcrel_1byte", 0, 1 * 8 }, - { "reloc_riprel_4byte", 0, 4 * 8 } + { "reloc_pcrel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, + { "reloc_pcrel_1byte", 0, 1 * 8, MCFixupKindInfo::FKF_IsPCRel }, + { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, + { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel } }; if (Kind < FirstTargetFixupKind) @@ -165,7 +166,8 @@ EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind, // If the fixup is pc-relative, we need to bias the value to be relative to // the start of the field, not the end of the field. if (FixupKind == MCFixupKind(X86::reloc_pcrel_4byte) || - FixupKind == MCFixupKind(X86::reloc_riprel_4byte)) + FixupKind == MCFixupKind(X86::reloc_riprel_4byte) || + FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load)) ImmOffset -= 4; if (FixupKind == MCFixupKind(X86::reloc_pcrel_1byte)) ImmOffset -= 1; @@ -197,6 +199,15 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, "Invalid rip-relative address"); EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); + unsigned FixupKind = X86::reloc_riprel_4byte; + + // movq loads are handled with a special relocation form which allows the + // linker to eliminate some loads for GOT references which end up in the + // same linkage unit. + if (MI.getOpcode() == X86::MOV64rm || + MI.getOpcode() == X86::MOV64rm_TC) + FixupKind = X86::reloc_riprel_4byte_movq_load; + // rip-relative addressing is actually relative to the *next* instruction. // Since an immediate can follow the mod/rm byte for an instruction, this // means that we need to bias the immediate field of the instruction with @@ -204,7 +215,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // expression to emit. int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0; - EmitImmediate(Disp, 4, MCFixupKind(X86::reloc_riprel_4byte), + EmitImmediate(Disp, 4, MCFixupKind(FixupKind), CurByte, OS, Fixups, -ImmSize); return; } @@ -269,7 +280,10 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // Emit the normal disp32 encoding. EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); ForceDisp32 = true; - } else if (Disp.getImm() == 0 && BaseReg != X86::EBP) { + } else if (Disp.getImm() == 0 && + // Base reg can't be anything that ends up with '5' as the base + // reg, it is the magic [*] nomenclature that indicates no base. + BaseRegNo != N86::EBP) { // Emit no displacement ModR/M byte EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); } else if (isDisp8(Disp.getImm())) { diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index f907614..cd56816 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -366,12 +366,3 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &FS, if (StackAlignment) stackAlignment = StackAlignment; } - -bool X86Subtarget::enablePostRAScheduler( - CodeGenOpt::Level OptLevel, - TargetSubtarget::AntiDepBreakMode& Mode, - RegClassVector& CriticalPathRCs) const { - Mode = TargetSubtarget::ANTIDEP_CRITICAL; - CriticalPathRCs.clear(); - return OptLevel >= CodeGenOpt::Aggressive; -} diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 50338d3..56220db 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -230,12 +230,6 @@ public: /// indicating the number of scheduling cycles of backscheduling that /// should be attempted. unsigned getSpecialAddressLatency() const; - - /// enablePostRAScheduler - X86 target is enabling post-alloc scheduling - /// at 'More' optimization level. - bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, - TargetSubtarget::AntiDepBreakMode& Mode, - RegClassVector& CriticalPathRCs) const; }; } // End llvm namespace diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index 56ddaf8..f13e6f3 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -22,7 +22,7 @@ #include "llvm/Target/TargetRegistry.h" using namespace llvm; -static const MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) { +static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) { Triple TheTriple(TT); switch (TheTriple.getOS()) { case Triple::Darwin: |