MachineInstr.h revision 943b5e117fe9a087f9aa529a2632c2d32cc22374
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
45890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos    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 {
74ceb408f6a263e319683209ae5c6f8d1e3e4d9b69Chris Lattner    GlobalValue *GV;    // LLVM global for MO_GlobalAddress.
7500876a2808f1a8061f7e0852c7949fc5074ecb04Misha Brukman    int64_t immedVal;   // Constant value for an explicit constant
768cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner    MachineBasicBlock *MBB;     // For MO_MachineBasicBlock type
777b55d4fce2c2b8eebbb1fc654400c7d46fd6bfbaChris Lattner    const char *SymbolName;     // For MO_ExternalSymbol type
7802597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    unsigned RegNo;            // For MO_Register number for an explicit register
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  ///
1142d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner  bool isRegister() const { return opType == MO_Register; }
11563b3d7113d93fda622c4954c6b1d046ce029044eChris Lattner  bool isImmediate() const { return opType == MO_Immediate; }
11668ab4c6367f34e6320c5f0ce22b85f800bdcfd81Chris Lattner  bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
11756cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  bool isFrameIndex() const { return opType == MO_FrameIndex; }
1183c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; }
11937efe6764568a3829fee26aba532283131d1a104Nate Begeman  bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; }
1203c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
1213c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
12235880f394fd547b9bec1e92e92ac68db9a931a58Misha Brukman
1239696a90ee66e1c6c818c8de3d9ffc32732d9d82fDuraid Madina  int64_t getImmedValue() const {
124c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isImmediate() && "Wrong MachineOperand accessor");
125c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    return contents.immedVal;
126c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  }
1278cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  MachineBasicBlock *getMachineBasicBlock() const {
128c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
129c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    return contents.MBB;
130c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  }
131dc4a4922d32b470acd68498d41e3b8130cf1e74eChris Lattner  void setMachineBasicBlock(MachineBasicBlock *MBB) {
132dc4a4922d32b470acd68498d41e3b8130cf1e74eChris Lattner    assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
133dc4a4922d32b470acd68498d41e3b8130cf1e74eChris Lattner    contents.MBB = MBB;
134dc4a4922d32b470acd68498d41e3b8130cf1e74eChris Lattner  }
135c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  int getFrameIndex() const {
136c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isFrameIndex() && "Wrong MachineOperand accessor");
1373bdfdfd10f73dcf17aa3381679e9be3e08a16d78Jeff Cohen    return (int)contents.immedVal;
1388cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  }
1393c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  unsigned getConstantPoolIndex() const {
140c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
1413bdfdfd10f73dcf17aa3381679e9be3e08a16d78Jeff Cohen    return (unsigned)contents.immedVal;
1423c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
14337efe6764568a3829fee26aba532283131d1a104Nate Begeman  unsigned getJumpTableIndex() const {
14437efe6764568a3829fee26aba532283131d1a104Nate Begeman    assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
14537efe6764568a3829fee26aba532283131d1a104Nate Begeman    return (unsigned)contents.immedVal;
14637efe6764568a3829fee26aba532283131d1a104Nate Begeman  }
1473c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  GlobalValue *getGlobal() const {
148c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isGlobalAddress() && "Wrong MachineOperand accessor");
149ceb408f6a263e319683209ae5c6f8d1e3e4d9b69Chris Lattner    return contents.GV;
1503c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
151ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner  int getOffset() const {
152404cb4f9fa2df50eac4d84b8a77c84a92188c6d5Evan Cheng    assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
153ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner        "Wrong MachineOperand accessor");
15402597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    return offset;
155ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner  }
1567b55d4fce2c2b8eebbb1fc654400c7d46fd6bfbaChris Lattner  const char *getSymbolName() const {
157c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isExternalSymbol() && "Wrong MachineOperand accessor");
1587b55d4fce2c2b8eebbb1fc654400c7d46fd6bfbaChris Lattner    return contents.SymbolName;
1593c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
1608cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner
161c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  /// MachineOperand methods for testing that work on any kind of
162c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  /// MachineOperand...
163c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  ///
16414be64018fb38d1fa535b9cd12d11371f4eba3b5Alkis Evlogimenos  bool            isUse           () const { return flags & USEFLAG; }
16514be64018fb38d1fa535b9cd12d11371f4eba3b5Alkis Evlogimenos  MachineOperand& setUse          ()       { flags |= USEFLAG; return *this; }
166c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  bool            isDef           () const { return flags & DEFFLAG; }
16714be64018fb38d1fa535b9cd12d11371f4eba3b5Alkis Evlogimenos  MachineOperand& setDef          ()       { flags |= DEFFLAG; return *this; }
168504fc5b7b5a9ffa9f82e95e7212015575030c7a7Vikram S. Adve
16968ab4c6367f34e6320c5f0ce22b85f800bdcfd81Chris Lattner  /// getReg - Returns the register number.
170c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  ///
171be766c72464116a445a02b542a450c4274bab5d0Alkis Evlogimenos  unsigned getReg() const {
17268ab4c6367f34e6320c5f0ce22b85f800bdcfd81Chris Lattner    assert(isRegister() && "This is not a register operand!");
17302597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    return contents.RegNo;
1747a4be9580e095ca4bffd16ec6ec4882f6270fb09Vikram S. Adve  }
175504fc5b7b5a9ffa9f82e95e7212015575030c7a7Vikram S. Adve
1764efeab208cf0fe7ae2f68bcdd1264a8fdb18826cChris Lattner  /// MachineOperand mutators.
177c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  ///
178786a518f47fca5521d036031f78e3f2470a7a49aChris Lattner  void setReg(unsigned Reg) {
17968ab4c6367f34e6320c5f0ce22b85f800bdcfd81Chris Lattner    assert(isRegister() && "This is not a register operand!");
18002597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    contents.RegNo = Reg;
181ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman  }
182b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattner
183e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  void setImmedValue(int64_t immVal) {
184c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    assert(isImmediate() && "Wrong MachineOperand mutator");
185c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke    contents.immedVal = immVal;
186c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  }
1879f495b54fa94dba4e0be59ba9736c7cf18d996d9Vikram S. Adve
188ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner  void setOffset(int Offset) {
18937efe6764568a3829fee26aba532283131d1a104Nate Begeman    assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
19037efe6764568a3829fee26aba532283131d1a104Nate Begeman            isJumpTableIndex()) &&
191ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner        "Wrong MachineOperand accessor");
19202597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    offset = Offset;
193ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner  }
194e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner
195e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// ChangeToImmediate - Replace this operand with a new immediate operand of
196e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// the specified value.  If an operand is known to be an immediate already,
197e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// the setImmedValue method should be used.
198e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  void ChangeToImmediate(int64_t ImmVal) {
199e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner    opType = MO_Immediate;
200e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner    contents.immedVal = ImmVal;
201e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  }
202e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner
203e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// ChangeToRegister - Replace this operand with a new register operand of
204e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// the specified value.  If an operand is known to be an register already,
205e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  /// the setReg method should be used.
206e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  void ChangeToRegister(unsigned Reg) {
2072d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner    opType = MO_Register;
20802597f3b8826e9760cee11ea07b4cfc5f260f736Chris Lattner    contents.RegNo = Reg;
209e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  }
210ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner
211697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
21298f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve
21369cacd471093e38a51e0e637fca1a1768b935136Vikram S. Adve  friend class MachineInstr;
21423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve};
21523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
21623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
217b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattner//===----------------------------------------------------------------------===//
2188b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner/// MachineInstr - Representation of each machine instruction.
2198b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner///
2209452b0797a80001920576d7e2ef4af05242cba69Chris Lattnerclass MachineInstr {
221c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  short Opcode;                         // the opcode
222943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  std::vector<MachineOperand> Operands; // the operands
223c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  MachineInstr* prev, *next;            // links for our intrusive list
224ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos  MachineBasicBlock* parent;            // pointer to the owning basic block
225c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke
226413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  // OperandComplete - Return true if it's illegal to add a new operand
227413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  bool OperandsComplete() const;
228a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve
229466b534a570f574ed485d875bbca8454f68dcb52Tanya Lattner  MachineInstr(const MachineInstr&);
2309452b0797a80001920576d7e2ef4af05242cba69Chris Lattner  void operator=(const MachineInstr&); // DO NOT IMPLEMENT
231c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos
232c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  // Intrusive list support
233c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  //
2341fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner  friend struct ilist_traits<MachineInstr>;
235c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos
2366a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advepublic:
2378b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner  /// MachineInstr ctor - This constructor reserve's space for numOperand
2388b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner  /// operands.
2398b915b4ed2c6e43413937ac71c0cbcf476ad1a98Chris Lattner  MachineInstr(short Opcode, unsigned numOperands);
240e8b57ef2603ed522083dc18e559ca4e20abf22aeVikram S. Adve
2417db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattner  /// MachineInstr ctor - Work exactly the same as the ctor above, except that
2427db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattner  /// the MachineInstr is created and added to the end of the specified basic
2437db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattner  /// block.
2447db458fb0768059f050d3a0f1a26818fa8e22712Chris Lattner  ///
245ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos  MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
246ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman
247aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos  ~MachineInstr();
248aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos
249ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos  const MachineBasicBlock* getParent() const { return parent; }
250ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos  MachineBasicBlock* getParent() { return parent; }
251ab8672c8bb83e722b856eac67863542ea7e0cbb2Alkis Evlogimenos
252c54839573cd9ffa6af33dc5190cc40d498534585Brian Gaeke  /// getOpcode - Returns the opcode of this MachineInstr.
253cd0b3a90aa34bd42d75d8d86f74ca4972145781dBrian Gaeke  ///
2542a90ba60175f93e7438165d8423100aa573c16c5Chris Lattner  const int getOpcode() const { return Opcode; }
2559f495b54fa94dba4e0be59ba9736c7cf18d996d9Vikram S. Adve
256cd0b3a90aa34bd42d75d8d86f74ca4972145781dBrian Gaeke  /// Access to explicit operands of the instruction.
257cd0b3a90aa34bd42d75d8d86f74ca4972145781dBrian Gaeke  ///
258943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  unsigned getNumOperands() const { return Operands.size(); }
259ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman
260572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  const MachineOperand& getOperand(unsigned i) const {
261a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve    assert(i < getNumOperands() && "getOperand() out of range!");
262943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    return Operands[i];
263572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  }
264572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  MachineOperand& getOperand(unsigned i) {
265a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve    assert(i < getNumOperands() && "getOperand() out of range!");
266943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    return Operands[i];
267572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  }
2686d6c3f86186333037f2fd3fb001e8b2998c080d9Chris Lattner
269a2bae305fb5a870c4ef753ed290a7ddea73ec82bVikram S. Adve
270b5159ed0cb7943e5938782f7693beb18342165ceTanya Lattner  /// clone - Create a copy of 'this' instruction that is identical in
271b5159ed0cb7943e5938782f7693beb18342165ceTanya Lattner  /// all ways except the the instruction has no parent, prev, or next.
272943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  MachineInstr* clone() const { return new MachineInstr(*this); }
2736b560918426182d2b46b899d609911d49f6739f7Chris Lattner
2746b560918426182d2b46b899d609911d49f6739f7Chris Lattner  /// removeFromParent - This method unlinks 'this' from the containing basic
2756b560918426182d2b46b899d609911d49f6739f7Chris Lattner  /// block, and returns it, but does not delete it.
2766b560918426182d2b46b899d609911d49f6739f7Chris Lattner  MachineInstr *removeFromParent();
2776b560918426182d2b46b899d609911d49f6739f7Chris Lattner
2786b560918426182d2b46b899d609911d49f6739f7Chris Lattner  /// eraseFromParent - This method unlinks 'this' from the containing basic
2796b560918426182d2b46b899d609911d49f6739f7Chris Lattner  /// block and deletes it.
2806b560918426182d2b46b899d609911d49f6739f7Chris Lattner  void eraseFromParent() {
2816b560918426182d2b46b899d609911d49f6739f7Chris Lattner    delete removeFromParent();
2826b560918426182d2b46b899d609911d49f6739f7Chris Lattner  }
283466b534a570f574ed485d875bbca8454f68dcb52Tanya Lattner
284a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  //
285a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  // Debugging support
286fa78fbf446b505767e838f9c188707183c57fc9cChris Lattner  //
287b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattner  void print(std::ostream &OS, const TargetMachine *TM) const;
288572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  void dump() const;
289572f5c8c0cf66cd6f53dda255cd8c4d8f27d8505Chris Lattner  friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
2902f898d207466bf233b55607e404baca302bc7b5eChris Lattner
291413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  //===--------------------------------------------------------------------===//
292943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  // Accessors to add operands when building up machine instructions.
293413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  //
294413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner
295943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  /// addRegOperand - Add a register operand.
296413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  ///
297943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  void addRegOperand(unsigned Reg,
298890f92328d5478e050d2eba8f4de24737a04a812Alkis Evlogimenos                     MachineOperand::UseType UTy = MachineOperand::Use) {
299943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
300943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_Register;
301943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = UTy;
302943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.RegNo = Reg;
303943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
30423e6bba592af68ba991ee6900978e81eb21a08afChris Lattner  }
30523e6bba592af68ba991ee6900978e81eb21a08afChris Lattner
3062d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner  /// addImmOperand - Add a zero extended constant argument to the
307413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  /// machine instruction.
308413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  ///
3092d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner  void addImmOperand(int64_t Val) {
310943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
311943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_Immediate;
312943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
313943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.immedVal = Val;
314943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
315413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner  }
316413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner
3178cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
318943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
319943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_MachineBasicBlock;
320943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
321943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.MBB = MBB;
322943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
3238cbfc75d17ee1c274116dc1aca3bc8e8ed2326c9Chris Lattner  }
324413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner
32556cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  /// addFrameIndexOperand - Add an abstract frame index to the instruction
32656cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  ///
32756cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  void addFrameIndexOperand(unsigned Idx) {
328943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
329943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_FrameIndex;
330943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
331943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.immedVal = Idx;
332943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
33356cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner  }
33456cf63f2f6db6ae47dec06489d09011ef6b0ee02Chris Lattner
3353c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// addConstantPoolndexOperand - Add a constant pool object index to the
3363c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// instruction.
3373c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  ///
338943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  void addConstantPoolIndexOperand(unsigned Idx, int Offset) {
339943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
340943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_ConstantPoolIndex;
341943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
342943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.immedVal = Idx;
343943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = Offset;
3443c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
3453c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner
34637efe6764568a3829fee26aba532283131d1a104Nate Begeman  /// addJumpTableIndexOperand - Add a jump table object index to the
34737efe6764568a3829fee26aba532283131d1a104Nate Begeman  /// instruction.
34837efe6764568a3829fee26aba532283131d1a104Nate Begeman  ///
349943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  void addJumpTableIndexOperand(unsigned Idx) {
350943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
351943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_JumpTableIndex;
352943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
353943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.immedVal = Idx;
354943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
35537efe6764568a3829fee26aba532283131d1a104Nate Begeman  }
35637efe6764568a3829fee26aba532283131d1a104Nate Begeman
357ea50fabfd4e5fad25a25b312f64a9b2a53363586Chris Lattner  void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
358943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
359943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_GlobalAddress;
360943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
361943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.GV = GV;
362943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = Offset;
3633c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
3643c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner
3653c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// addExternalSymbolOperand - Add an external symbol operand to this instr
3663c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  ///
367ea50fabfd4e5fad25a25b312f64a9b2a53363586Chris Lattner  void addExternalSymbolOperand(const char *SymName) {
368943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    MachineOperand &Op = AddNewOperand();
369943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.opType = MachineOperand::MO_ExternalSymbol;
370943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.flags = 0;
371943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.contents.SymbolName = SymName;
372943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Op.offset = 0;
3733c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
3747ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner
3757ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner  //===--------------------------------------------------------------------===//
3767ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner  // Accessors used to modify instructions in place.
3777ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner  //
3787ad6be7b01a902f532eebb607306f7b3f4627718Chris Lattner
3793c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// setOpcode - Replace the opcode of the current instruction with a new one.
3803c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  ///
3812a90ba60175f93e7438165d8423100aa573c16c5Chris Lattner  void setOpcode(unsigned Op) { Opcode = Op; }
3823c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner
3833c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
3843c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  /// fewer operand than it started with.
3853c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  ///
3863c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  void RemoveOperand(unsigned i) {
387943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Operands.erase(Operands.begin()+i);
388943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  }
389943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattnerprivate:
390943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner  MachineOperand &AddNewOperand() {
391943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    assert(!OperandsComplete() &&
392943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner           "Trying to add an operand to a machine instr that is already done!");
393943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    Operands.push_back(MachineOperand());
394943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner    return Operands.back();
3953c8cbe6567c94fdd24ec9b2b8b5c5cc1b01a8c58Chris Lattner  }
396a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve};
39723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
398b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattner//===----------------------------------------------------------------------===//
399593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Adve// Debugging Support
400593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Adve
401b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattnerstd::ostream& operator<<(std::ostream &OS, const MachineInstr &MI);
402b05497e0ca1ba2e7f57b792cc160e5d1c8579582Chris Lattnerstd::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
403136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve
404d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
405d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
40623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve#endif
407