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