Convert backend to use passes, implement X86TargetMachine
[oota-llvm.git] / lib / Target / X86 / X86ISelSimple.cpp
1 //===-- InstSelectSimple.cpp - A simple instruction selector for x86 ------===//
2 //
3 // This file defines a simple peephole instruction selector for the x86 platform
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "X86.h"
8 #include "X86InstrInfo.h"
9 #include "llvm/Function.h"
10 #include "llvm/iTerminators.h"
11 #include "llvm/Type.h"
12 #include "llvm/Constants.h"
13 #include "llvm/Pass.h"
14 #include "llvm/CodeGen/MachineFunction.h"
15 #include "llvm/CodeGen/MachineInstrBuilder.h"
16 #include "llvm/Support/InstVisitor.h"
17 #include <map>
18
19 namespace {
20   struct ISel : public FunctionPass, InstVisitor<ISel> {
21     TargetMachine &TM;
22     MachineFunction *F;                    // The function we are compiling into
23     MachineBasicBlock *BB;                 // The current MBB we are compiling
24
25     unsigned CurReg;
26     std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
27
28     ISel(TargetMachine &tm)
29       : TM(tm), F(0), BB(0), CurReg(MRegisterInfo::FirstVirtualRegister) {}
30
31     /// runOnFunction - Top level implementation of instruction selection for
32     /// the entire function.
33     ///
34     bool runOnFunction(Function &Fn) {
35       F = new MachineFunction(&Fn, TM);
36       visit(Fn);
37       RegMap.clear();
38       F = 0;
39       return false;  // We never modify the LLVM itself.
40     }
41
42     /// visitBasicBlock - This method is called when we are visiting a new basic
43     /// block.  This simply creates a new MachineBasicBlock to emit code into
44     /// and adds it to the current MachineFunction.  Subsequent visit* for
45     /// instructions will be invoked for all instructions in the basic block.
46     ///
47     void visitBasicBlock(BasicBlock &LLVM_BB) {
48       BB = new MachineBasicBlock();
49       // FIXME: Use the auto-insert form when it's available
50       F->getBasicBlockList().push_back(BB);
51     }
52
53     // Visitation methods for various instructions.  These methods simply emit
54     // fixed X86 code for each instruction.
55     //
56     void visitReturnInst(ReturnInst &RI);
57     void visitAdd(BinaryOperator &B);
58
59     void visitInstruction(Instruction &I) {
60       std::cerr << "Cannot instruction select: " << I;
61       abort();
62     }
63
64     
65     /// copyConstantToRegister - Output the instructions required to put the
66     /// specified constant into the specified register.
67     ///
68     void copyConstantToRegister(Constant *C, unsigned Reg);
69
70     /// getReg - This method turns an LLVM value into a register number.  This
71     /// is guaranteed to produce the same register number for a particular value
72     /// every time it is queried.
73     ///
74     unsigned getReg(Value &V) { return getReg(&V); }  // Allow references
75     unsigned getReg(Value *V) {
76       unsigned &Reg = RegMap[V];
77       if (Reg == 0)
78         Reg = CurReg++;
79
80       // If this operand is a constant, emit the code to copy the constant into
81       // the register here...
82       //
83       if (Constant *C = dyn_cast<Constant>(V))
84         copyConstantToRegister(C, Reg);
85
86       return Reg;
87     }
88
89   };
90 }
91
92
93 /// copyConstantToRegister - Output the instructions required to put the
94 /// specified constant into the specified register.
95 ///
96 void ISel::copyConstantToRegister(Constant *C, unsigned R) {
97   assert (!isa<ConstantExpr>(C) && "Constant expressions not yet handled!\n");
98
99   switch (C->getType()->getPrimitiveID()) {
100   case Type::SByteTyID:
101     BuildMI(BB, X86::MOVir8, R).addSImm(cast<ConstantSInt>(C)->getValue());
102     break;
103   case Type::UByteTyID:
104     BuildMI(BB, X86::MOVir8, R).addZImm(cast<ConstantUInt>(C)->getValue());
105     break;
106   case Type::ShortTyID:
107     BuildMI(BB, X86::MOVir16, R).addSImm(cast<ConstantSInt>(C)->getValue());
108     break;
109   case Type::UShortTyID:
110     BuildMI(BB, X86::MOVir16, R).addZImm(cast<ConstantUInt>(C)->getValue());
111     break;
112   case Type::IntTyID:
113     BuildMI(BB, X86::MOVir32, R).addSImm(cast<ConstantSInt>(C)->getValue());
114     break;
115   case Type::UIntTyID:
116     BuildMI(BB, X86::MOVir32, R).addZImm(cast<ConstantUInt>(C)->getValue());
117     break;
118   default: assert(0 && "Type not handled yet!");      
119   }
120 }
121
122
123 /// 'ret' instruction - Here we are interested in meeting the x86 ABI.  As such,
124 /// we have the following possibilities:
125 ///
126 ///   ret void: No return value, simply emit a 'ret' instruction
127 ///   ret sbyte, ubyte : Extend value into EAX and return
128 ///   ret short, ushort: Extend value into EAX and return
129 ///   ret int, uint    : Move value into EAX and return
130 ///   ret pointer      : Move value into EAX and return
131 ///   ret long, ulong  : Move value into EAX/EDX (?) and return
132 ///   ret float/double : ?  Top of FP stack?  XMM0?
133 ///
134 void ISel::visitReturnInst(ReturnInst &I) {
135   if (I.getNumOperands() != 0) {  // Not 'ret void'?
136     // Move result into a hard register... then emit a ret
137     visitInstruction(I);  // abort
138   }
139
140   // Emit a simple 'ret' instruction... appending it to the end of the basic
141   // block
142   BuildMI(BB, X86::RET, 0);
143 }
144
145
146 /// 'add' instruction - Simply turn this into an x86 reg,reg add instruction.
147 void ISel::visitAdd(BinaryOperator &B) {
148   unsigned Op0r = getReg(B.getOperand(0)), Op1r = getReg(B.getOperand(1));
149   unsigned DestReg = getReg(B);
150
151   switch (B.getType()->getPrimitiveSize()) {
152   case 1:   // UByte, SByte
153     BuildMI(BB, X86::ADDrr8, DestReg).addReg(Op0r).addReg(Op1r);
154     break;
155   case 2:   // UShort, Short
156     BuildMI(BB, X86::ADDrr16, DestReg).addReg(Op0r).addReg(Op1r);
157     break;
158   case 4:   // UInt, Int
159     BuildMI(BB, X86::ADDrr32, DestReg).addReg(Op0r).addReg(Op1r);
160     break;
161
162   case 8:   // ULong, Long
163   default:
164     visitInstruction(B);  // abort
165   }
166 }
167
168 /// createSimpleX86InstructionSelector - This pass converts an LLVM function
169 /// into a machine code representation is a very simple peep-hole fashion.  The
170 /// generated code sucks but the implementation is nice and simple.
171 ///
172 Pass *createSimpleX86InstructionSelector(TargetMachine &TM) {
173   return new ISel(TM);
174 }