MachineInstr.h revision 171ce440aa1eca773a4025362efb2b498c562d71
148486893f46d2e12e926682a3ecb908716bc66c4Chris Lattner//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
2ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman//
36fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//                     The LLVM Compiler Infrastructure
46fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//
56fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell// This file was developed by the LLVM research group and is distributed under
66fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details.
7ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman//
86fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//===----------------------------------------------------------------------===//
9a730c864227b287cdfad5f5f3d5d0808c9f422bbChris Lattner//
10a730c864227b287cdfad5f5f3d5d0808c9f422bbChris Lattner// This file contains the declaration of the MachineInstr class, which is the
11ef6a6a69ff1e1b709d0acb315b9f6c926c67a778Misha Brukman// basic representation for all target dependent machine instructions used by
12a730c864227b287cdfad5f5f3d5d0808c9f422bbChris Lattner// the back end.
13a730c864227b287cdfad5f5f3d5d0808c9f422bbChris Lattner//
14a730c864227b287cdfad5f5f3d5d0808c9f422bbChris Lattner//===----------------------------------------------------------------------===//
1523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
1623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve#ifndef LLVM_CODEGEN_MACHINEINSTR_H
1723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve#define LLVM_CODEGEN_MACHINEINSTR_H
1823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
19551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/iterator"
209696a90ee66e1c6c818c8de3d9ffc32732d9d82fDuraid Madina#include "llvm/Support/DataTypes.h"
21376ad9fa9f66facc7100186f0a1f56c1be858ff5Chris Lattner#include <vector>
227598a1a9a8ad9b974e428e24606c108aa3ba1431Chris Lattner#include <cassert>
23be583b914d8156b99d3da264d5adca37fee8dbc9John Criswell
24d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
26054c1f6cb6f3a680fe4b8447880ed960fd7fe441Chris Lattnerclass Value;
27054c1f6cb6f3a680fe4b8447880ed960fd7fe441Chris Lattnerclass Function;
287db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattnerclass MachineBasicBlock;
29fa78fbf446b505767e838f9c188707183c57fc9cChris Lattnerclass TargetMachine;
303c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattnerclass GlobalValue;
31054c1f6cb6f3a680fe4b8447880ed960fd7fe441Chris Lattner
321fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnertemplate <typename T> struct ilist_traits;
331fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnertemplate <typename T> struct ilist;
34c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos
35b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattner//===----------------------------------------------------------------------===//
36ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman// class MachineOperand
37ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman//
3823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   Representation of each machine instruction operand.
3900876a2808f1a8061f7e0852c7949fc5074ecb04Misha Brukman//
403c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattnerstruct MachineOperand {
41890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenosprivate:
42890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  // Bit fields of the flags variable used for different operand properties
43890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  enum {
44890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos    DEFFLAG     = 0x01,       // this is a def of the operand
45d74ea2bbd8bb630331f35ead42d385249bd42af8Chris Lattner    USEFLAG     = 0x02        // this is a use of the operand
46890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  };
47890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos
48890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenospublic:
49890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  // UseType - This enum describes how the machine operand is used by
50890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  // the instruction. Note that the MachineInstr/Operator class
51890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  // currently uses bool arguments to represent this information
52890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  // instead of an enum.  Eventually this should change over to use
53890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  // this _easier to read_ representation instead.
54890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  //
55890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  enum UseType {
56890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos    Use = USEFLAG,        /// only read
57890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos    Def = DEFFLAG,        /// only written
58890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos    UseAndDef = Use | Def /// read AND written
59890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos  };
60890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos
6123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  enum MachineOperandType {
622d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner    MO_Register,                // Register operand.
6363b3d7113d93fda622c4954c6b1d046ce029044eChris Lattner    MO_Immediate,               // Immediate Operand
648cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner    MO_MachineBasicBlock,       // MachineBasicBlock reference
6556cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner    MO_FrameIndex,              // Abstract Stack Frame Index
663c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner    MO_ConstantPoolIndex,       // Address of indexed Constant in Constant Pool
6737efe6764568a3829fee26aba532283131d1a104Nate Begeman    MO_JumpTableIndex,          // Address of indexed Jump Table for switch
683c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner    MO_ExternalSymbol,          // Name of external global symbol
69410354fe0c052141dadeca939395743f8dd58e38Chris Lattner    MO_GlobalAddress            // Address of a global value
7023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  };
71ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman
726a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adveprivate:
736a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  union {
746e994b74921d8519472a087246d7a56731e958d4Chris Lattner    GlobalValue *GV;          // For MO_GlobalAddress.
756e994b74921d8519472a087246d7a56731e958d4Chris Lattner    MachineBasicBlock *MBB;   // For MO_MachineBasicBlock.
766e994b74921d8519472a087246d7a56731e958d4Chris Lattner    const char *SymbolName;   // For MO_ExternalSymbol.
776e994b74921d8519472a087246d7a56731e958d4Chris Lattner    unsigned RegNo;           // For MO_Register.
786e994b74921d8519472a087246d7a56731e958d4Chris Lattner    int64_t immedVal;         // For MO_Immediate and MO_*Index.
79c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  } contents;
80773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka
811a33e6eb7477ecc015f3aadbd47f1c1434003a66Chris Lattner  char flags;                   // see bit field definitions above
828cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  MachineOperandType opType:8;  // Pack into 8 bits efficiently after flags.
8302597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner
8402597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner  /// offset - Offset to address of global or external, only valid for
8502597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner  /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
8602597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner  int offset;
87c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke
88943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  MachineOperand() {}
896a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advepublic:
9002597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner  MachineOperand(const MachineOperand &M) {
9102597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    *this = M;
923c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
93a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve
947b55d4fce2c2b8eebbb1fc654400c7d46fd6bfbaChris Lattner  ~MachineOperand() {}
95ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman
963c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  const MachineOperand &operator=(const MachineOperand &MO) {
97c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    contents = MO.contents;
983c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner    flags    = MO.flags;
993c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner    opType   = MO.opType;
10002597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    offset   = MO.offset;
1013c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner    return *this;
1023c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
1033c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner
1040eda78a3729a917592a89ede933d7b7df82e0dc3Brian Gaeke  /// getType - Returns the MachineOperandType for this operand.
105ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman  ///
106133f079c8cf966d2222c2dda2de56d2cc600497eChris Lattner  MachineOperandType getType() const { return opType; }
107572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner
108f216421181393fd3993b47960de44ad448710fb9Alkis Evlogimenos  /// getUseType - Returns the MachineOperandUseType of this operand.
109f216421181393fd3993b47960de44ad448710fb9Alkis Evlogimenos  ///
110c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  UseType getUseType() const { return UseType(flags & (USEFLAG|DEFFLAG)); }
111f216421181393fd3993b47960de44ad448710fb9Alkis Evlogimenos
112c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  /// Accessors that tell you what kind of MachineOperand you're looking at.
113c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  ///
114930ab738c7d323cf9552bba2652af6aa361e9967Chris Lattner  bool isReg() const { return opType == MO_Register; }
115930ab738c7d323cf9552bba2652af6aa361e9967Chris Lattner  bool isImm() const { return opType == MO_Immediate; }
116930ab738c7d323cf9552bba2652af6aa361e9967Chris Lattner  bool isMBB() const { return opType == MO_MachineBasicBlock; }
117930ab738c7d323cf9552bba2652af6aa361e9967Chris Lattner
1182d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner  bool isRegister() const { return opType == MO_Register; }
11963b3d7113d93fda622c4954c6b1d046ce029044eChris Lattner  bool isImmediate() const { return opType == MO_Immediate; }
12068ab4c6367f34e6320c5f0ce22b85f800bdcfd81Chris Lattner  bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
12156cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  bool isFrameIndex() const { return opType == MO_FrameIndex; }
1223c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; }
12337efe6764568a3829fee26aba532283131d1a104Nate Begeman  bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; }
1243c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
1253c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
12635880f394fd547b9bec1e92e92ac68db9a931a58Misha Brukman
127171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner  int64_t getImm() const {
128171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner    assert(isImm() && "Wrong MachineOperand accessor");
129171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner    return contents.immedVal;
130171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner  }
131171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner
1329696a90ee66e1c6c818c8de3d9ffc32732d9d82fDuraid Madina  int64_t getImmedValue() const {
133171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner    assert(isImm() && "Wrong MachineOperand accessor");
134c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    return contents.immedVal;
135c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  }
1368cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  MachineBasicBlock *getMachineBasicBlock() const {
137c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
138c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    return contents.MBB;
139c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  }
140dc4a4922d32b470acd68498d41e3b8130cf1e74eChris Lattner  void setMachineBasicBlock(MachineBasicBlock *MBB) {
141dc4a4922d32b470acd68498d41e3b8130cf1e74eChris Lattner    assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
142dc4a4922d32b470acd68498d41e3b8130cf1e74eChris Lattner    contents.MBB = MBB;
143dc4a4922d32b470acd68498d41e3b8130cf1e74eChris Lattner  }
144c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  int getFrameIndex() const {
145c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isFrameIndex() && "Wrong MachineOperand accessor");
1463bdfdfd10f73dcf17aa3381679e9be3e08a16d78Jeff Cohen    return (int)contents.immedVal;
1478cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  }
1483c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  unsigned getConstantPoolIndex() const {
149c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
1503bdfdfd10f73dcf17aa3381679e9be3e08a16d78Jeff Cohen    return (unsigned)contents.immedVal;
1513c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
15237efe6764568a3829fee26aba532283131d1a104Nate Begeman  unsigned getJumpTableIndex() const {
15337efe6764568a3829fee26aba532283131d1a104Nate Begeman    assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
15437efe6764568a3829fee26aba532283131d1a104Nate Begeman    return (unsigned)contents.immedVal;
15537efe6764568a3829fee26aba532283131d1a104Nate Begeman  }
1563c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  GlobalValue *getGlobal() const {
157c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isGlobalAddress() && "Wrong MachineOperand accessor");
158ceb408f6a263e319683209ae5c6f8d1e3e4d9b69Chris Lattner    return contents.GV;
1593c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
160ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner  int getOffset() const {
161404cb4f9fa2df50eac4d84b8a77c84a92188c6d5Evan Cheng    assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
162ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner        "Wrong MachineOperand accessor");
16302597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    return offset;
164ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner  }
1657b55d4fce2c2b8eebbb1fc654400c7d46fd6bfbaChris Lattner  const char *getSymbolName() const {
166c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isExternalSymbol() && "Wrong MachineOperand accessor");
1677b55d4fce2c2b8eebbb1fc654400c7d46fd6bfbaChris Lattner    return contents.SymbolName;
1683c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
1698cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner
170c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  /// MachineOperand methods for testing that work on any kind of
171c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  /// MachineOperand...
172c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  ///
173171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner  bool isUse() const { return flags & USEFLAG; }
174171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner  bool isDef() const { return flags & DEFFLAG; }
175171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner  MachineOperand &setUse() { flags |= USEFLAG; return *this; }
176171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner  MachineOperand &setDef() { flags |= DEFFLAG; return *this; }
177504fc5b7b5a9ffa9f82e95e7212015575030c7a7Vikram S. Adve
17868ab4c6367f34e6320c5f0ce22b85f800bdcfd81Chris Lattner  /// getReg - Returns the register number.
179c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  ///
180be766c72464116a445a02b542a450c4274bab5d0Alkis Evlogimenos  unsigned getReg() const {
18168ab4c6367f34e6320c5f0ce22b85f800bdcfd81Chris Lattner    assert(isRegister() && "This is not a register operand!");
18202597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    return contents.RegNo;
1837a4be9580e095ca4bffd16ec6ec4882f6270fb09Vikram S. Adve  }
184504fc5b7b5a9ffa9f82e95e7212015575030c7a7Vikram S. Adve
1854efeab208cf0fe7ae2f68bcdd1264a8fdb18826cChris Lattner  /// MachineOperand mutators.
186c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  ///
187786a518f47fca5521d036031f78e3f2470a7a49aChris Lattner  void setReg(unsigned Reg) {
18868ab4c6367f34e6320c5f0ce22b85f800bdcfd81Chris Lattner    assert(isRegister() && "This is not a register operand!");
18902597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    contents.RegNo = Reg;
190ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman  }
191b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattner
192e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  void setImmedValue(int64_t immVal) {
193171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner    assert(isImm() && "Wrong MachineOperand mutator");
194171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner    contents.immedVal = immVal;
195171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner  }
196171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner  void setImm(int64_t immVal) {
197171ce440aa1eca773a4025362efb2b498c562d71Chris Lattner    assert(isImm() && "Wrong MachineOperand mutator");
198c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    contents.immedVal = immVal;
199c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  }
2009f495b54fa94dba4e0be59ba9736c7cf18d996d9Vikram S. Adve
201ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner  void setOffset(int Offset) {
20237efe6764568a3829fee26aba532283131d1a104Nate Begeman    assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
20337efe6764568a3829fee26aba532283131d1a104Nate Begeman            isJumpTableIndex()) &&
204ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner        "Wrong MachineOperand accessor");
20502597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    offset = Offset;
206ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner  }
207e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner
208e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// ChangeToImmediate - Replace this operand with a new immediate operand of
209e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// the specified value.  If an operand is known to be an immediate already,
210e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// the setImmedValue method should be used.
211e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  void ChangeToImmediate(int64_t ImmVal) {
212e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner    opType = MO_Immediate;
213e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner    contents.immedVal = ImmVal;
214e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  }
215e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner
216e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// ChangeToRegister - Replace this operand with a new register operand of
217e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// the specified value.  If an operand is known to be an register already,
218e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// the setReg method should be used.
219e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  void ChangeToRegister(unsigned Reg) {
2202d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner    opType = MO_Register;
22102597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    contents.RegNo = Reg;
222e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  }
223ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner
224697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
22598f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve
22669cacd471093e38a51e0e637fca1a1768b935136Vikram S. Adve  friend class MachineInstr;
22723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve};
22823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
22923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
230b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattner//===----------------------------------------------------------------------===//
2318b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner/// MachineInstr - Representation of each machine instruction.
2328b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner///
2339452b0797a80001920576d7e2ef4af05242cba69Chris Lattnerclass MachineInstr {
234c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  short Opcode;                         // the opcode
235943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  std::vector<MachineOperand> Operands; // the operands
236c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  MachineInstr* prev, *next;            // links for our intrusive list
237ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos  MachineBasicBlock* parent;            // pointer to the owning basic block
238c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke
239413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  // OperandComplete - Return true if it's illegal to add a new operand
240413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  bool OperandsComplete() const;
241a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve
242466b534a570f574ed485d875bbca8454f68dcb52Tanya Lattner  MachineInstr(const MachineInstr&);
2439452b0797a80001920576d7e2ef4af05242cba69Chris Lattner  void operator=(const MachineInstr&); // DO NOT IMPLEMENT
244c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos
245c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  // Intrusive list support
246c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  //
2471fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner  friend struct ilist_traits<MachineInstr>;
248c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos
2496a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advepublic:
2508b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner  /// MachineInstr ctor - This constructor reserve's space for numOperand
2518b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner  /// operands.
2528b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner  MachineInstr(short Opcode, unsigned numOperands);
253e8b57ef2603ed522083dc18e559ca4e20abf22aeVikram S. Adve
2547db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattner  /// MachineInstr ctor - Work exactly the same as the ctor above, except that
2557db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattner  /// the MachineInstr is created and added to the end of the specified basic
2567db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattner  /// block.
2577db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattner  ///
258ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos  MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
259ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman
260aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos  ~MachineInstr();
261aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos
262ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos  const MachineBasicBlock* getParent() const { return parent; }
263ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos  MachineBasicBlock* getParent() { return parent; }
264ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos
265c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  /// getOpcode - Returns the opcode of this MachineInstr.
266cd0b3a90aa34bd42d75d8d86f74ca4972145781dBrian Gaeke  ///
2672a90ba60175f93e7438165d8423100aa573c16c5Chris Lattner  const int getOpcode() const { return Opcode; }
2689f495b54fa94dba4e0be59ba9736c7cf18d996d9Vikram S. Adve
269cd0b3a90aa34bd42d75d8d86f74ca4972145781dBrian Gaeke  /// Access to explicit operands of the instruction.
270cd0b3a90aa34bd42d75d8d86f74ca4972145781dBrian Gaeke  ///
271943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  unsigned getNumOperands() const { return Operands.size(); }
272ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman
273572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  const MachineOperand& getOperand(unsigned i) const {
274a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve    assert(i < getNumOperands() && "getOperand() out of range!");
275943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    return Operands[i];
276572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  }
277572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  MachineOperand& getOperand(unsigned i) {
278a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve    assert(i < getNumOperands() && "getOperand() out of range!");
279943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    return Operands[i];
280572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  }
2816d6c3f86186333037f2fd3fb001e8b2998c080d9Chris Lattner
282a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve
283b5159ed0cb7943e5938782f7693beb18342165ceTanya Lattner  /// clone - Create a copy of 'this' instruction that is identical in
284b5159ed0cb7943e5938782f7693beb18342165ceTanya Lattner  /// all ways except the the instruction has no parent, prev, or next.
285943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  MachineInstr* clone() const { return new MachineInstr(*this); }
2866b560918426182d2b46b899d609911d49f6739f7Chris Lattner
2876b560918426182d2b46b899d609911d49f6739f7Chris Lattner  /// removeFromParent - This method unlinks 'this' from the containing basic
2886b560918426182d2b46b899d609911d49f6739f7Chris Lattner  /// block, and returns it, but does not delete it.
2896b560918426182d2b46b899d609911d49f6739f7Chris Lattner  MachineInstr *removeFromParent();
2906b560918426182d2b46b899d609911d49f6739f7Chris Lattner
2916b560918426182d2b46b899d609911d49f6739f7Chris Lattner  /// eraseFromParent - This method unlinks 'this' from the containing basic
2926b560918426182d2b46b899d609911d49f6739f7Chris Lattner  /// block and deletes it.
2936b560918426182d2b46b899d609911d49f6739f7Chris Lattner  void eraseFromParent() {
2946b560918426182d2b46b899d609911d49f6739f7Chris Lattner    delete removeFromParent();
2956b560918426182d2b46b899d609911d49f6739f7Chris Lattner  }
296466b534a570f574ed485d875bbca8454f68dcb52Tanya Lattner
297a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  //
298a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  // Debugging support
299fa78fbf446b505767e838f9c188707183c57fc9cChris Lattner  //
300b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattner  void print(std::ostream &OS, const TargetMachine *TM) const;
301572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  void dump() const;
302572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
3032f898d207466bf233b55607e404baca302bc7b5eChris Lattner
304413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  //===--------------------------------------------------------------------===//
305943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  // Accessors to add operands when building up machine instructions.
306413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  //
307413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner
308943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  /// addRegOperand - Add a register operand.
309413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  ///
310943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  void addRegOperand(unsigned Reg,
311890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos                     MachineOperand::UseType UTy = MachineOperand::Use) {
312943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
313943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_Register;
314943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = UTy;
315943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.RegNo = Reg;
316943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
31723e6bba592af68ba991ee6900978e81eb21a08afChris Lattner  }
31823e6bba592af68ba991ee6900978e81eb21a08afChris Lattner
3192d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner  /// addImmOperand - Add a zero extended constant argument to the
320413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  /// machine instruction.
321413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  ///
3222d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner  void addImmOperand(int64_t Val) {
323943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
324943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_Immediate;
325943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
326943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.immedVal = Val;
327943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
328413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  }
329413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner
3308cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
331943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
332943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_MachineBasicBlock;
333943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
334943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.MBB = MBB;
335943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
3368cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  }
337413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner
33856cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  /// addFrameIndexOperand - Add an abstract frame index to the instruction
33956cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  ///
34056cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  void addFrameIndexOperand(unsigned Idx) {
341943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
342943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_FrameIndex;
343943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
344943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.immedVal = Idx;
345943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
34656cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  }
34756cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner
3483c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// addConstantPoolndexOperand - Add a constant pool object index to the
3493c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// instruction.
3503c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  ///
351943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  void addConstantPoolIndexOperand(unsigned Idx, int Offset) {
352943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
353943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_ConstantPoolIndex;
354943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
355943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.immedVal = Idx;
356943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = Offset;
3573c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
3583c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner
35937efe6764568a3829fee26aba532283131d1a104Nate Begeman  /// addJumpTableIndexOperand - Add a jump table object index to the
36037efe6764568a3829fee26aba532283131d1a104Nate Begeman  /// instruction.
36137efe6764568a3829fee26aba532283131d1a104Nate Begeman  ///
362943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  void addJumpTableIndexOperand(unsigned Idx) {
363943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
364943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_JumpTableIndex;
365943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
366943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.immedVal = Idx;
367943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
36837efe6764568a3829fee26aba532283131d1a104Nate Begeman  }
36937efe6764568a3829fee26aba532283131d1a104Nate Begeman
370ea50fabfd4e5fad25a25b312f64a9b2a53363586Chris Lattner  void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
371943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
372943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_GlobalAddress;
373943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
374943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.GV = GV;
375943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = Offset;
3763c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
3773c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner
3783c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// addExternalSymbolOperand - Add an external symbol operand to this instr
3793c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  ///
380ea50fabfd4e5fad25a25b312f64a9b2a53363586Chris Lattner  void addExternalSymbolOperand(const char *SymName) {
381943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
382943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_ExternalSymbol;
383943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
384943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.SymbolName = SymName;
385943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
3863c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
3877ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner
3887ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner  //===--------------------------------------------------------------------===//
3897ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner  // Accessors used to modify instructions in place.
3907ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner  //
3917ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner
3923c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// setOpcode - Replace the opcode of the current instruction with a new one.
3933c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  ///
3942a90ba60175f93e7438165d8423100aa573c16c5Chris Lattner  void setOpcode(unsigned Op) { Opcode = Op; }
3953c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner
3963c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
3973c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// fewer operand than it started with.
3983c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  ///
3993c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  void RemoveOperand(unsigned i) {
400943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Operands.erase(Operands.begin()+i);
401943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  }
402943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattnerprivate:
403943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  MachineOperand &AddNewOperand() {
404943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    assert(!OperandsComplete() &&
405943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner           "Trying to add an operand to a machine instr that is already done!");
406943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Operands.push_back(MachineOperand());
407943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    return Operands.back();
4083c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
409a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve};
41023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
411b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattner//===----------------------------------------------------------------------===//
412593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Adve// Debugging Support
413593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Adve
414b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattnerstd::ostream& operator<<(std::ostream &OS, const MachineInstr &MI);
415b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattnerstd::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
416136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve
417d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
418d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
41923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve#endif
420