Initial checkin of Machine Code representation for X86 backend. This will
eventually be merged with the sparc backend. llvm-svn: 4286
This commit is contained in:
parent
f11dd2092b
commit
aed689d1aa
|
@ -0,0 +1,64 @@
|
||||||
|
//===-- llvm/CodeGen/MBasicBlock.h - Machine Specific BB rep ----*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// This class provides a way to represent a basic block in a machine-specific
|
||||||
|
// form. A basic block is represented as a list of machine specific
|
||||||
|
// instructions.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef CODEGEN_MBASICBLOCK_H
|
||||||
|
#define CODEGEN_MBASICBLOCK_H
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/MInstruction.h"
|
||||||
|
#include "Support/ilist"
|
||||||
|
|
||||||
|
class MBasicBlock {
|
||||||
|
MBasicBlock *Prev, *Next;
|
||||||
|
iplist<MInstruction> InstList;
|
||||||
|
// FIXME: we should maintain a pointer to the function we are embedded into!
|
||||||
|
public:
|
||||||
|
MBasicBlock() {}
|
||||||
|
|
||||||
|
// Provide accessors for the MBasicBlock list...
|
||||||
|
typedef iplist<MInstruction> InstListType;
|
||||||
|
typedef InstListType::iterator iterator;
|
||||||
|
typedef InstListType::const_iterator const_iterator;
|
||||||
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||||
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
/// Instruction iterator methods
|
||||||
|
///
|
||||||
|
inline iterator begin() { return InstList.begin(); }
|
||||||
|
inline const_iterator begin() const { return InstList.begin(); }
|
||||||
|
inline iterator end () { return InstList.end(); }
|
||||||
|
inline const_iterator end () const { return InstList.end(); }
|
||||||
|
|
||||||
|
inline reverse_iterator rbegin() { return InstList.rbegin(); }
|
||||||
|
inline const_reverse_iterator rbegin() const { return InstList.rbegin(); }
|
||||||
|
inline reverse_iterator rend () { return InstList.rend(); }
|
||||||
|
inline const_reverse_iterator rend () const { return InstList.rend(); }
|
||||||
|
|
||||||
|
inline unsigned size() const { return InstList.size(); }
|
||||||
|
inline bool empty() const { return InstList.empty(); }
|
||||||
|
inline const MInstruction &front() const { return InstList.front(); }
|
||||||
|
inline MInstruction &front() { return InstList.front(); }
|
||||||
|
inline const MInstruction &back() const { return InstList.back(); }
|
||||||
|
inline MInstruction &back() { return InstList.back(); }
|
||||||
|
|
||||||
|
/// getInstList() - Return the underlying instruction list container. You
|
||||||
|
/// need to access it directly if you want to modify it currently.
|
||||||
|
///
|
||||||
|
const InstListType &getInstList() const { return InstList; }
|
||||||
|
InstListType &getInstList() { return InstList; }
|
||||||
|
|
||||||
|
private: // Methods used to maintain doubly linked list of blocks...
|
||||||
|
friend class ilist_traits<MBasicBlock>;
|
||||||
|
|
||||||
|
MBasicBlock *getPrev() const { return Prev; }
|
||||||
|
MBasicBlock *getNext() const { return Next; }
|
||||||
|
void setPrev(MBasicBlock *P) { Prev = P; }
|
||||||
|
void setNext(MBasicBlock *N) { Next = N; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,70 @@
|
||||||
|
//===-- llvm/CodeGen/MFunction.h - Machine Specific Function ----*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// This class provides a way to represent a function in a machine-specific form.
|
||||||
|
// A function is represented as a list of machine specific blocks along with a
|
||||||
|
// list of registers that are used to receive arguments for the function.
|
||||||
|
//
|
||||||
|
// In the machine specific representation for a function, the function may
|
||||||
|
// either be in SSA form or in a register based form. When in SSA form, the
|
||||||
|
// register numbers are indexes into the RegDefMap that the MFunction contains.
|
||||||
|
// This allows accessing SSA use-def information by using the source register
|
||||||
|
// number for a use.
|
||||||
|
//
|
||||||
|
// After register allocation occurs, all of the register numbers in a function
|
||||||
|
// refer to real hardware registers and the RegDefMap is cleared.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef CODEGEN_MFUNCTION_H
|
||||||
|
#define CODEGEN_MFUNCTION_H
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/MBasicBlock.h"
|
||||||
|
#include <iosfwd>
|
||||||
|
class MInstructionInfo;
|
||||||
|
|
||||||
|
class MFunction {
|
||||||
|
iplist<MBasicBlock> BasicBlocks;
|
||||||
|
// FIXME: This should contain a pointer to the LLVM function
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// print - Provide a way to get a simple debugging dump. This dumps the
|
||||||
|
/// machine code in a simple "assembly" language that is not really suitable
|
||||||
|
/// for an assembler, but is useful for debugging. This is completely target
|
||||||
|
/// independant.
|
||||||
|
///
|
||||||
|
void print(std::ostream &OS, const MInstructionInfo &MII) const;
|
||||||
|
void dump(const MInstructionInfo &MII) const;
|
||||||
|
|
||||||
|
// Provide accessors for the MBasicBlock list...
|
||||||
|
typedef iplist<MBasicBlock> BasicBlockListType;
|
||||||
|
typedef BasicBlockListType::iterator iterator;
|
||||||
|
typedef BasicBlockListType::const_iterator const_iterator;
|
||||||
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||||
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||||
|
|
||||||
|
// Provide accessors for basic blocks...
|
||||||
|
const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
|
||||||
|
BasicBlockListType &getBasicBlockList() { return BasicBlocks; }
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// BasicBlock iterator forwarding functions
|
||||||
|
//
|
||||||
|
iterator begin() { return BasicBlocks.begin(); }
|
||||||
|
const_iterator begin() const { return BasicBlocks.begin(); }
|
||||||
|
iterator end () { return BasicBlocks.end(); }
|
||||||
|
const_iterator end () const { return BasicBlocks.end(); }
|
||||||
|
|
||||||
|
reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
|
||||||
|
const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
|
||||||
|
reverse_iterator rend () { return BasicBlocks.rend(); }
|
||||||
|
const_reverse_iterator rend () const { return BasicBlocks.rend(); }
|
||||||
|
|
||||||
|
unsigned size() const { return BasicBlocks.size(); }
|
||||||
|
bool empty() const { return BasicBlocks.empty(); }
|
||||||
|
const MBasicBlock &front() const { return BasicBlocks.front(); }
|
||||||
|
MBasicBlock &front() { return BasicBlocks.front(); }
|
||||||
|
const MBasicBlock &back() const { return BasicBlocks.back(); }
|
||||||
|
MBasicBlock &back() { return BasicBlocks.back(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,51 @@
|
||||||
|
//===-- CodeGen/MInstBuilder.h - Simplify creation of MInstcn's -*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// This file exposes a function named BuildMInst that is useful for dramatically
|
||||||
|
// simplifying how MInstruction's are created. Instead of using code like this:
|
||||||
|
//
|
||||||
|
// M = new MInstruction(BB, X86::ADDrr32, DestReg);
|
||||||
|
// M->addOperand(Arg0Reg, MOperand::Register);
|
||||||
|
// M->addOperand(Arg1Reg, MOperand::Register);
|
||||||
|
//
|
||||||
|
// we can now use code like this:
|
||||||
|
//
|
||||||
|
// M = BuildMInst(BB, X86::ADDrr8, DestReg).addReg(Arg0Reg).addReg(Arg1Reg);
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_CODEGEN_MINSTBUILDER_H
|
||||||
|
#define LLVM_CODEGEN_MINSTBUILDER_H
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/MInstruction.h"
|
||||||
|
|
||||||
|
struct MInstructionBuilder {
|
||||||
|
MInstruction *MI;
|
||||||
|
|
||||||
|
MInstructionBuilder(MInstruction *mi) : MI(mi) {}
|
||||||
|
|
||||||
|
/// Allow automatic conversion to the machine instruction we are working on.
|
||||||
|
///
|
||||||
|
operator MInstruction*() const { return MI; }
|
||||||
|
|
||||||
|
/// addReg - Add a new register operand...
|
||||||
|
///
|
||||||
|
MInstructionBuilder &addReg(unsigned RegNo) {
|
||||||
|
MI->addOperand(RegNo, MOperand::Register);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/// BuildMInst - Builder interface. Specify how to create the initial
|
||||||
|
/// instruction itself.
|
||||||
|
///
|
||||||
|
inline MInstructionBuilder BuildMInst(unsigned Opcode, unsigned DestReg = 0) {
|
||||||
|
return MInstructionBuilder(new MInstruction(Opcode, DestReg));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MInstructionBuilder BuildMInst(MBasicBlock *BB, unsigned Opcode,
|
||||||
|
unsigned DestReg = 0) {
|
||||||
|
return MInstructionBuilder(new MInstruction(BB, Opcode, DestReg));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,150 @@
|
||||||
|
//===-- llvm/CodeGen/MInstruction.h - Machine Instruction -------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// This class represents a single machine instruction for the LLVM backend.
|
||||||
|
// This instruction is represented in a completely generic way to allow all
|
||||||
|
// backends to share a common representation. MInstructions are embedded into
|
||||||
|
// MBasicBlocks, and are maintained as a doubly linked list.
|
||||||
|
//
|
||||||
|
// Because there are a lot of machine instruction that may be in use at a time
|
||||||
|
// (being manipulated), we are sure to keep a very compact representation that
|
||||||
|
// is extremely light-weight.
|
||||||
|
//
|
||||||
|
// This class is used to represent an instruction when it is in SSA form as well
|
||||||
|
// as when it has been register allocated to use physical registers.
|
||||||
|
//
|
||||||
|
// FIXME: This should eventually be merged with the MachineInstr class.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef CODEGEN_MINSTRUCTION_H
|
||||||
|
#define CODEGEN_MINSTRUCTION_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
template<typename NodeTy> struct ilist_traits;
|
||||||
|
class MBasicBlock;
|
||||||
|
|
||||||
|
/// MOperand - This class represents a single operand in an instruction.
|
||||||
|
/// Interpretation of this operand is not really possible without information
|
||||||
|
/// from the machine instruction that it is embedded into.
|
||||||
|
///
|
||||||
|
class MOperand {
|
||||||
|
union {
|
||||||
|
unsigned uVal;
|
||||||
|
int iVal;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
MOperand(unsigned Value) : uVal(Value) {}
|
||||||
|
MOperand(int Value) : iVal(Value) {}
|
||||||
|
|
||||||
|
/// Interpretation - This enum is used by the MInstruction class to interpret
|
||||||
|
/// the untyped value field of the operand.
|
||||||
|
enum Interpretation {
|
||||||
|
Register, // This is some register number
|
||||||
|
SignExtImmediate, // This is a sign extended immediate
|
||||||
|
ZeroExtImmediate, // This is a zero extended immediate
|
||||||
|
PCRelativeDisp // This is a displacement relative to the PC
|
||||||
|
// FIXME: We need a symbolic value here, like global variable address
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned getUnsignedValue() const { return uVal; }
|
||||||
|
unsigned getSignedValue() const { return iVal; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// MInstruction - Represent a single machine instruction in the code generator.
|
||||||
|
/// This is meant to be a light weight representation that is completely
|
||||||
|
/// independant of the target machine being code generated for.
|
||||||
|
///
|
||||||
|
class MInstruction {
|
||||||
|
MInstruction *Prev, *Next; // Doubly linked list of instructions...
|
||||||
|
|
||||||
|
unsigned Opcode; // Opcode of the instruction
|
||||||
|
unsigned Dest; // Destination register written (or 0 if none)
|
||||||
|
|
||||||
|
std::vector<MOperand> Operands; // Operands of the instruction...
|
||||||
|
|
||||||
|
/// OperandInterpretation - This array specifies how the operands of the
|
||||||
|
/// instruction are to be interpreted (is it a register?, an immediate
|
||||||
|
/// constant?, a PC relative displacement?, etc...). Only four values are
|
||||||
|
/// allowed, so any instruction with more than four operands (should be
|
||||||
|
/// exceedingly rare, perhaps only PHI nodes) are assumed to have register
|
||||||
|
/// operands beyond the fourth.
|
||||||
|
///
|
||||||
|
unsigned char OperandInterpretation[4];
|
||||||
|
public:
|
||||||
|
/// MInstruction ctor - Create a new machine instruction, with the specified
|
||||||
|
/// opcode and destination register. Operands are then added with the
|
||||||
|
/// addOperand method.
|
||||||
|
///
|
||||||
|
MInstruction(unsigned O = 0, unsigned D = 0) : Opcode(O), Dest(D) {}
|
||||||
|
|
||||||
|
/// MInstruction ctor - Create a new instruction, and append it to the
|
||||||
|
/// specified basic block.
|
||||||
|
///
|
||||||
|
MInstruction(MBasicBlock *BB, unsigned Opcode = 0, unsigned Dest = 0);
|
||||||
|
|
||||||
|
/// getOpcode - Return the opcode for this machine instruction. The value of
|
||||||
|
/// the opcode defines how to interpret the operands of the instruction.
|
||||||
|
///
|
||||||
|
unsigned getOpcode() const { return Opcode; }
|
||||||
|
|
||||||
|
/// getDestinationReg - This method returns the register written to by this
|
||||||
|
/// instruction. If this returns zero, the instruction does not produce a
|
||||||
|
/// value, because register #0 is always the garbage marker.
|
||||||
|
///
|
||||||
|
unsigned getDestinationReg() const { return Dest; }
|
||||||
|
|
||||||
|
/// setDestinationReg - This method changes the register written to by this
|
||||||
|
/// instruction. Note that if SSA form is currently active then the SSA table
|
||||||
|
/// needs to be updated to match this, thus this method shouldn't be used
|
||||||
|
/// directly.
|
||||||
|
///
|
||||||
|
void setDestinationReg(unsigned R) { Dest = R; }
|
||||||
|
|
||||||
|
/// getNumOperands - Return the number of operands the instruction currently
|
||||||
|
/// has.
|
||||||
|
///
|
||||||
|
unsigned getNumOperands() const { return Operands.size(); }
|
||||||
|
|
||||||
|
/// getOperandInterpretation - Return the interpretation of operand #Op
|
||||||
|
///
|
||||||
|
MOperand::Interpretation getOperandInterpretation(unsigned Op) const {
|
||||||
|
if (Op < 4) return (MOperand::Interpretation)OperandInterpretation[Op];
|
||||||
|
return MOperand::Register; // Operands >= 4 are all registers
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned getRegisterOperand(unsigned Op) const {
|
||||||
|
assert(getOperandInterpretation(Op) == MOperand::Register &&
|
||||||
|
"Operand isn't a register!");
|
||||||
|
return Operands[Op].getUnsignedValue();
|
||||||
|
}
|
||||||
|
int getSignExtOperand(unsigned Op) const {
|
||||||
|
assert(getOperandInterpretation(Op) == MOperand::SignExtImmediate &&
|
||||||
|
"Operand isn't a sign extended immediate!");
|
||||||
|
return Operands[Op].getSignedValue();
|
||||||
|
}
|
||||||
|
unsigned getZeroExtOperand(unsigned Op) const {
|
||||||
|
assert(getOperandInterpretation(Op) == MOperand::ZeroExtImmediate &&
|
||||||
|
"Operand isn't a zero extended immediate!");
|
||||||
|
return Operands[Op].getUnsignedValue();
|
||||||
|
}
|
||||||
|
int getPCRelativeOperand(unsigned Op) const {
|
||||||
|
assert(getOperandInterpretation(Op) == MOperand::PCRelativeDisp &&
|
||||||
|
"Operand isn't a PC relative displacement!");
|
||||||
|
return Operands[Op].getSignedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// addOperand - Add a new operand to the instruction with the specified value
|
||||||
|
/// and interpretation.
|
||||||
|
///
|
||||||
|
void addOperand(unsigned Value, MOperand::Interpretation Ty);
|
||||||
|
|
||||||
|
private: // Methods used to maintain doubly linked list of instructions...
|
||||||
|
friend class ilist_traits<MInstruction>;
|
||||||
|
|
||||||
|
MInstruction *getPrev() const { return Prev; }
|
||||||
|
MInstruction *getNext() const { return Next; }
|
||||||
|
void setPrev(MInstruction *P) { Prev = P; }
|
||||||
|
void setNext(MInstruction *N) { Next = N; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue