//===-- llvm/CodeGen/MachineOperand.h - MachineOperand class ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the MachineOperand class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
#define LLVM_CODEGEN_MACHINEOPERAND_H

#include "llvm/Support/DataTypes.h"
#include <vector>
#include <cassert>
#include <iosfwd>

namespace llvm {
  
class ConstantFP;
class MachineBasicBlock;
class GlobalValue;
class MachineInstr;
class TargetMachine;
class MachineRegisterInfo;
  
/// MachineOperand class - Representation of each machine instruction operand.
///
class MachineOperand {
public:
  enum MachineOperandType {
    MO_Register,                // Register operand.
    MO_Immediate,               // Immediate Operand
    MO_FPImmediate,
    MO_MachineBasicBlock,       // MachineBasicBlock reference
    MO_FrameIndex,              // Abstract Stack Frame Index
    MO_ConstantPoolIndex,       // Address of indexed Constant in Constant Pool
    MO_JumpTableIndex,          // Address of indexed Jump Table for switch
    MO_ExternalSymbol,          // Name of external global symbol
    MO_GlobalAddress            // Address of a global value
  };

private:
  /// OpKind - Specify what kind of operand this is.  This discriminates the
  /// union.
  MachineOperandType OpKind : 8;
  
  /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register
  /// operands.
  
  /// IsDef - True if this is a def, false if this is a use of the register.
  ///
  bool IsDef : 1;
  
  /// IsImp - True if this is an implicit def or use, false if it is explicit.
  ///
  bool IsImp : 1;

  /// IsKill - True if this instruction is the last use of the register on this
  /// path through the function.  This is only valid on uses of registers.
  bool IsKill : 1;

  /// IsDead - True if this register is never used by a subsequent instruction.
  /// This is only valid on definitions of registers.
  bool IsDead : 1;

  /// SubReg - Subregister number, only valid for MO_Register.  A value of 0
  /// indicates the MO_Register has no subReg.
  unsigned char SubReg;
  
  /// ParentMI - This is the instruction that this operand is embedded into. 
  /// This is valid for all operand types, when the operand is in an instr.
  MachineInstr *ParentMI;

  /// Contents union - This contains the payload for the various operand types.
  union {
    MachineBasicBlock *MBB;   // For MO_MachineBasicBlock.
    ConstantFP *CFP;          // For MO_FPImmediate.
    int64_t ImmVal;           // For MO_Immediate.

    struct {                  // For MO_Register.
      unsigned RegNo;
      MachineOperand **Prev;  // Access list for register.
      MachineOperand *Next;
    } Reg;
    
    /// OffsetedInfo - This struct contains the offset and an object identifier.
    /// this represent the object as with an optional offset from it.
    struct {
      union {
        int Index;                // For MO_*Index - The index itself.
        const char *SymbolName;   // For MO_ExternalSymbol.
        GlobalValue *GV;          // For MO_GlobalAddress.
      } Val;
      int Offset;   // An offset from the object.
    } OffsetedInfo;
  } Contents;
  
  explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {}
public:
  MachineOperand(const MachineOperand &M) {
    *this = M;
  }
  
  ~MachineOperand() {}
  
  /// getType - Returns the MachineOperandType for this operand.
  ///
  MachineOperandType getType() const { return OpKind; }

  /// getParent - Return the instruction that this operand belongs to.
  ///
  MachineInstr *getParent() { return ParentMI; }
  const MachineInstr *getParent() const { return ParentMI; }
  
  void print(std::ostream &os, const TargetMachine *TM = 0) const;

  /// Accessors that tell you what kind of MachineOperand you're looking at.
  ///
  bool isRegister() const { return OpKind == MO_Register; }
  bool isImmediate() const { return OpKind == MO_Immediate; }
  bool isFPImmediate() const { return OpKind == MO_FPImmediate; }
  bool isMachineBasicBlock() const { return OpKind == MO_MachineBasicBlock; }
  bool isFrameIndex() const { return OpKind == MO_FrameIndex; }
  bool isConstantPoolIndex() const { return OpKind == MO_ConstantPoolIndex; }
  bool isJumpTableIndex() const { return OpKind == MO_JumpTableIndex; }
  bool isGlobalAddress() const { return OpKind == MO_GlobalAddress; }
  bool isExternalSymbol() const { return OpKind == MO_ExternalSymbol; }

  bool isReg() const { return OpKind == MO_Register; }
  bool isImm() const { return OpKind == MO_Immediate; }
  bool isMBB() const { return OpKind == MO_MachineBasicBlock; }
  bool isFI() const { return OpKind == MO_FrameIndex; }
  bool isCPI() const { return OpKind == MO_ConstantPoolIndex; }
  bool isJTI() const { return OpKind == MO_JumpTableIndex; }
  bool isGlobal() const { return OpKind == MO_GlobalAddress; }
  bool isSymbol() const { return OpKind == MO_ExternalSymbol; }
  
  //===--------------------------------------------------------------------===//
  // Accessors for Register Operands
  //===--------------------------------------------------------------------===//

  /// getReg - Returns the register number.
  unsigned getReg() const {
    assert(isRegister() && "This is not a register operand!");
    return Contents.Reg.RegNo;
  }
  
  unsigned getSubReg() const {
    assert(isRegister() && "Wrong MachineOperand accessor");
    return (unsigned)SubReg;
  }
  
  bool isUse() const { 
    assert(isRegister() && "Wrong MachineOperand accessor");
    return !IsDef;
  }
  
  bool isDef() const {
    assert(isRegister() && "Wrong MachineOperand accessor");
    return IsDef;
  }
  
  bool isImplicit() const { 
    assert(isRegister() && "Wrong MachineOperand accessor");
    return IsImp;
  }
  
  bool isDead() const {
    assert(isRegister() && "Wrong MachineOperand accessor");
    return IsDead;
  }
  
  bool isKill() const {
    assert(isRegister() && "Wrong MachineOperand accessor");
    return IsKill;
  }
  
  /// getNextOperandForReg - Return the next MachineOperand in the function that
  /// uses or defines this register.
  MachineOperand *getNextOperandForReg() const {
    assert(isRegister() && "This is not a register operand!");
    return Contents.Reg.Next;
  }

  //===--------------------------------------------------------------------===//
  // Mutators for Register Operands
  //===--------------------------------------------------------------------===//
  
  /// Change the register this operand corresponds to.
  ///
  void setReg(unsigned Reg);
  
  void setSubReg(unsigned subReg) {
    assert(isRegister() && "Wrong MachineOperand accessor");
    SubReg = (unsigned char)subReg;
  }
  
  void setIsUse(bool Val = true) {
    assert(isRegister() && "Wrong MachineOperand accessor");
    IsDef = !Val;
  }
  
  void setIsDef(bool Val = true) {
    assert(isRegister() && "Wrong MachineOperand accessor");
    IsDef = Val;
  }

  void setImplicit(bool Val = true) { 
    assert(isRegister() && "Wrong MachineOperand accessor");
    IsImp = Val;
  }

  void setIsKill(bool Val = true) {
    assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
    IsKill = Val;
  }
  
  void setIsDead(bool Val = true) {
    assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
    IsDead = Val;
  }


  //===--------------------------------------------------------------------===//
  // Accessors for various operand types.
  //===--------------------------------------------------------------------===//
  
  int64_t getImm() const {
    assert(isImmediate() && "Wrong MachineOperand accessor");
    return Contents.ImmVal;
  }
  
  ConstantFP *getFPImm() const {
    assert(isFPImmediate() && "Wrong MachineOperand accessor");
    return Contents.CFP;
  }
  
  MachineBasicBlock *getMBB() const {
    assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
    return Contents.MBB;
  }

  int getIndex() const {
    assert((isFrameIndex() || isConstantPoolIndex() || isJumpTableIndex()) &&
           "Wrong MachineOperand accessor");
    return Contents.OffsetedInfo.Val.Index;
  }
  
  GlobalValue *getGlobal() const {
    assert(isGlobalAddress() && "Wrong MachineOperand accessor");
    return Contents.OffsetedInfo.Val.GV;
  }
  
  int getOffset() const {
    assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
           "Wrong MachineOperand accessor");
    return Contents.OffsetedInfo.Offset;
  }
  
  const char *getSymbolName() const {
    assert(isExternalSymbol() && "Wrong MachineOperand accessor");
    return Contents.OffsetedInfo.Val.SymbolName;
  }
  
  //===--------------------------------------------------------------------===//
  // Mutators for various operand types.
  //===--------------------------------------------------------------------===//
  
  void setImm(int64_t immVal) {
    assert(isImmediate() && "Wrong MachineOperand mutator");
    Contents.ImmVal = immVal;
  }

  void setOffset(int Offset) {
    assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
        "Wrong MachineOperand accessor");
    Contents.OffsetedInfo.Offset = Offset;
  }
  
  void setIndex(int Idx) {
    assert((isFrameIndex() || isConstantPoolIndex() || isJumpTableIndex()) &&
           "Wrong MachineOperand accessor");
    Contents.OffsetedInfo.Val.Index = Idx;
  }
  
  void setMBB(MachineBasicBlock *MBB) {
    assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
    Contents.MBB = MBB;
  }
  
  //===--------------------------------------------------------------------===//
  // Other methods.
  //===--------------------------------------------------------------------===//
  
  /// isIdenticalTo - Return true if this operand is identical to the specified
  /// operand. Note: This method ignores isKill and isDead properties.
  bool isIdenticalTo(const MachineOperand &Other) const;
  
  /// ChangeToImmediate - Replace this operand with a new immediate operand of
  /// the specified value.  If an operand is known to be an immediate already,
  /// the setImm method should be used.
  void ChangeToImmediate(int64_t ImmVal);
  
  /// ChangeToRegister - Replace this operand with a new register operand of
  /// the specified value.  If an operand is known to be an register already,
  /// the setReg method should be used.
  void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
                        bool isKill = false, bool isDead = false);
  
  //===--------------------------------------------------------------------===//
  // Construction methods.
  //===--------------------------------------------------------------------===//
  
  static MachineOperand CreateImm(int64_t Val) {
    MachineOperand Op(MachineOperand::MO_Immediate);
    Op.setImm(Val);
    return Op;
  }
  
  static MachineOperand CreateFPImm(ConstantFP *CFP) {
    MachineOperand Op(MachineOperand::MO_FPImmediate);
    Op.Contents.CFP = CFP;
    return Op;
  }
  
  static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
                                  bool isKill = false, bool isDead = false,
                                  unsigned SubReg = 0) {
    MachineOperand Op(MachineOperand::MO_Register);
    Op.IsDef = isDef;
    Op.IsImp = isImp;
    Op.IsKill = isKill;
    Op.IsDead = isDead;
    Op.Contents.Reg.RegNo = Reg;
    Op.Contents.Reg.Prev = 0;
    Op.Contents.Reg.Next = 0;
    Op.SubReg = SubReg;
    return Op;
  }
  static MachineOperand CreateMBB(MachineBasicBlock *MBB) {
    MachineOperand Op(MachineOperand::MO_MachineBasicBlock);
    Op.setMBB(MBB);
    return Op;
  }
  static MachineOperand CreateFI(unsigned Idx) {
    MachineOperand Op(MachineOperand::MO_FrameIndex);
    Op.setIndex(Idx);
    return Op;
  }
  static MachineOperand CreateCPI(unsigned Idx, int Offset) {
    MachineOperand Op(MachineOperand::MO_ConstantPoolIndex);
    Op.setIndex(Idx);
    Op.setOffset(Offset);
    return Op;
  }
  static MachineOperand CreateJTI(unsigned Idx) {
    MachineOperand Op(MachineOperand::MO_JumpTableIndex);
    Op.setIndex(Idx);
    return Op;
  }
  static MachineOperand CreateGA(GlobalValue *GV, int Offset) {
    MachineOperand Op(MachineOperand::MO_GlobalAddress);
    Op.Contents.OffsetedInfo.Val.GV = GV;
    Op.setOffset(Offset);
    return Op;
  }
  static MachineOperand CreateES(const char *SymName, int Offset = 0) {
    MachineOperand Op(MachineOperand::MO_ExternalSymbol);
    Op.Contents.OffsetedInfo.Val.SymbolName = SymName;
    Op.setOffset(Offset);
    return Op;
  }
  const MachineOperand &operator=(const MachineOperand &MO) {
    OpKind   = MO.OpKind;
    IsDef    = MO.IsDef;
    IsImp    = MO.IsImp;
    IsKill   = MO.IsKill;
    IsDead   = MO.IsDead;
    SubReg   = MO.SubReg;
    ParentMI = MO.ParentMI;
    Contents = MO.Contents;
    return *this;
  }

  friend class MachineInstr;
  friend class MachineRegisterInfo;
private:
  //===--------------------------------------------------------------------===//
  // Methods for handling register use/def lists.
  //===--------------------------------------------------------------------===//

  /// isOnRegUseList - Return true if this operand is on a register use/def list
  /// or false if not.  This can only be called for register operands that are
  /// part of a machine instruction.
  bool isOnRegUseList() const {
    assert(isReg() && "Can only add reg operand to use lists");
    return Contents.Reg.Prev != 0;
  }
  
  /// AddRegOperandToRegInfo - Add this register operand to the specified
  /// MachineRegisterInfo.  If it is null, then the next/prev fields should be
  /// explicitly nulled out.
  void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo);

  void RemoveRegOperandFromRegInfo() {
    assert(isOnRegUseList() && "Can only add reg operand to use lists");
    // Unlink this from the doubly linked list of operands.
    MachineOperand *NextOp = Contents.Reg.Next;
    *Contents.Reg.Prev = NextOp; 
    if (NextOp) {
      assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!");
      NextOp->Contents.Reg.Prev = Contents.Reg.Prev;
    }
    Contents.Reg.Prev = 0;
    Contents.Reg.Next = 0;
  }
};

inline std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) {
  MO.print(OS, 0);
  return OS;
}

} // End llvm namespace

#endif
