Add more information to the EFLAGS note.
[oota-llvm.git] / lib / Target / X86 / X86InstrInfo.h
index 01b80a974c78fa7416a06cfb0ccacb0b6d28fb80..f5b0cc9152727d4d3d83660b64051b1cb459e7bb 100644 (file)
@@ -17,7 +17,7 @@
 #include "llvm/Target/TargetInstrInfo.h"
 #include "X86.h"
 #include "X86RegisterInfo.h"
-#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 
 namespace llvm {
@@ -44,6 +44,15 @@ namespace X86 {
     COND_O  = 13,
     COND_P  = 14,
     COND_S  = 15,
+
+    // Artificial condition codes. These are used by AnalyzeBranch
+    // to indicate a block terminated with two conditional branches to
+    // the same location. This occurs in code using FCMP_OEQ or FCMP_UNE,
+    // which can't be represented on x86 with a single condition. These
+    // are never used in MachineInstrs.
+    COND_NE_OR_P,
+    COND_NP_OR_E,
+
     COND_INVALID
   };
     
@@ -221,27 +230,34 @@ namespace X86II {
     LOCKShift = 19,
     LOCK = 1 << LOCKShift,
 
-    // Bits 20 -> 23 are unused
+    // Segment override prefixes. Currently we just need ability to address
+    // stuff in gs and fs segments.
+    SegOvrShift = 20,
+    SegOvrMask  = 3 << SegOvrShift,
+    FS          = 1 << SegOvrShift,
+    GS          = 2 << SegOvrShift,
+
+    // Bits 22 -> 23 are unused
     OpcodeShift   = 24,
     OpcodeMask    = 0xFF << OpcodeShift
   };
 }
 
 inline static bool isScale(const MachineOperand &MO) {
-  return MO.isImmediate() &&
+  return MO.isImm() &&
     (MO.getImm() == 1 || MO.getImm() == 2 ||
      MO.getImm() == 4 || MO.getImm() == 8);
 }
 
 inline static bool isMem(const MachineInstr *MI, unsigned Op) {
-  if (MI->getOperand(Op).isFrameIndex()) return true;
+  if (MI->getOperand(Op).isFI()) return true;
   return Op+4 <= MI->getNumOperands() &&
-    MI->getOperand(Op  ).isRegister() && isScale(MI->getOperand(Op+1)) &&
-    MI->getOperand(Op+2).isRegister() &&
-    (MI->getOperand(Op+3).isImmediate() ||
-     MI->getOperand(Op+3).isGlobalAddress() ||
-     MI->getOperand(Op+3).isConstantPoolIndex() ||
-     MI->getOperand(Op+3).isJumpTableIndex());
+    MI->getOperand(Op  ).isReg() && isScale(MI->getOperand(Op+1)) &&
+    MI->getOperand(Op+2).isReg() &&
+    (MI->getOperand(Op+3).isImm() ||
+     MI->getOperand(Op+3).isGlobal() ||
+     MI->getOperand(Op+3).isCPI() ||
+     MI->getOperand(Op+3).isJTI());
 }
 
 class X86InstrInfo : public TargetInstrInfoImpl {
@@ -269,19 +285,20 @@ public:
   ///
   virtual const X86RegisterInfo &getRegisterInfo() const { return RI; }
 
-  // Return true if the instruction is a register to register move and
-  // leave the source and dest operands in the passed parameters.
-  //
-  bool isMoveInstr(const MachineInstr& MI, unsigned& sourceReg,
-                   unsigned& destReg) const;
-  unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
-  unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
+  /// Return true if the instruction is a register to register move and return
+  /// the source and dest operands and their sub-register indices by reference.
+  virtual bool isMoveInstr(const MachineInstr &MI,
+                           unsigned &SrcReg, unsigned &DstReg,
+                           unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+
+  unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const;
+  unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const;
 
   bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const;
   void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                      unsigned DestReg, const MachineInstr *Orig) const;
 
-  bool isInvariantLoad(MachineInstr *MI) const;
+  bool isInvariantLoad(const MachineInstr *MI) const;
 
   /// convertToThreeAddress - This method must be implemented by targets that
   /// set the M_CONVERTIBLE_TO_3_ADDR flag.  When this flag is set, the target
@@ -306,12 +323,13 @@ public:
   virtual bool isUnpredicatedTerminator(const MachineInstr* MI) const;
   virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
                              MachineBasicBlock *&FBB,
-                             std::vector<MachineOperand> &Cond) const;
+                             SmallVectorImpl<MachineOperand> &Cond,
+                             bool AllowModify) const;
   virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
   virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
                                 MachineBasicBlock *FBB,
-                                const std::vector<MachineOperand> &Cond) const;
-  virtual void copyRegToReg(MachineBasicBlock &MBB,
+                            const SmallVectorImpl<MachineOperand> &Cond) const;
+  virtual bool copyRegToReg(MachineBasicBlock &MBB,
                             MachineBasicBlock::iterator MI,
                             unsigned DestReg, unsigned SrcReg,
                             const TargetRegisterClass *DestRC,
@@ -350,22 +368,23 @@ public:
   /// folding and return true, otherwise it should return false.  If it folds
   /// the instruction, it is likely that the MachineInstruction the iterator
   /// references has been changed.
-  virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
-                                          MachineInstr* MI,
-                                          SmallVectorImpl<unsigned> &Ops,
-                                          int FrameIndex) const;
+  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+                                              MachineInstr* MI,
+                                           const SmallVectorImpl<unsigned> &Ops,
+                                              int FrameIndex) const;
 
   /// foldMemoryOperand - Same as the previous version except it allows folding
   /// of any load and store from / to any address, not just from a specific
   /// stack slot.
-  virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
-                                          MachineInstr* MI,
-                                  SmallVectorImpl<unsigned> &Ops,
-                                  MachineInstr* LoadMI) const;
+  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+                                              MachineInstr* MI,
+                                           const SmallVectorImpl<unsigned> &Ops,
+                                              MachineInstr* LoadMI) const;
 
   /// canFoldMemoryOperand - Returns true if the specified load / store is
   /// folding is possible.
-  virtual bool canFoldMemoryOperand(MachineInstr*, SmallVectorImpl<unsigned> &) const;
+  virtual bool canFoldMemoryOperand(const MachineInstr*,
+                                    const SmallVectorImpl<unsigned> &) const;
 
   /// unfoldMemoryOperand - Separate a single instruction which folded a load or
   /// a store or a load and a store into two or more instruction. If this is
@@ -384,10 +403,13 @@ public:
   virtual unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
                                       bool UnfoldLoad, bool UnfoldStore) const;
   
-  virtual bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const;
-  virtual bool ReverseBranchCondition(std::vector<MachineOperand> &Cond) const;
+  virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
+  virtual
+  bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
 
-  const TargetRegisterClass *getPointerRegClass() const;
+  /// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine
+  /// instruction that defines the specified register class.
+  bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const;
 
   // getBaseOpcodeFor - This function returns the "base" X86 opcode for the
   // specified machine instruction.
@@ -405,7 +427,6 @@ public:
   }
   
   static unsigned sizeOfImm(const TargetInstrDesc *Desc);
-  static unsigned getX86RegNum(unsigned RegNo);
   static bool isX86_64ExtendedReg(const MachineOperand &MO);
   static unsigned determineREX(const MachineInstr &MI);
 
@@ -413,11 +434,17 @@ public:
   ///
   virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
 
+  /// getGlobalBaseReg - Return a virtual register initialized with the
+  /// the global base register value. Output instructions required to
+  /// initialize the register in the function entry block, if necessary.
+  ///
+  unsigned getGlobalBaseReg(MachineFunction *MF) const;
+
 private:
-  MachineInstr* foldMemoryOperand(MachineFunction &MF,
-                                  MachineInstr* MI,
-                                  unsigned OpNum,
-                                  SmallVector<MachineOperand,4> &MOs) const;
+  MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+                                      MachineInstr* MI,
+                                      unsigned OpNum,
+                                      const SmallVectorImpl<MachineOperand> &MOs) const;
 };
 
 } // End llvm namespace