blob: 38aa994a25172c5b9b67ba680dece7d2fedc11c3 [file] [log] [blame]
Dan Gohman1adf1b02008-08-19 21:45:35 +00001//===-- X86FastISel.cpp - X86 FastISel implementation ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the X86-specific support for the FastISel class. Much
11// of the target-specific code is generated by tablegen in the file
12// X86GenFastISel.inc, which is #included here.
13//
14//===----------------------------------------------------------------------===//
15
16#include "X86.h"
Evan Cheng8b19e562008-09-03 06:44:39 +000017#include "X86InstrBuilder.h"
Dan Gohman1adf1b02008-08-19 21:45:35 +000018#include "X86ISelLowering.h"
Evan Cheng88e30412008-09-03 01:04:47 +000019#include "X86RegisterInfo.h"
20#include "X86Subtarget.h"
Dan Gohman22bb3112008-08-22 00:20:26 +000021#include "X86TargetMachine.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000022#include "llvm/CodeGen/FastISel.h"
Owen Anderson667d8f72008-08-29 17:45:56 +000023#include "llvm/CodeGen/MachineRegisterInfo.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000024
25using namespace llvm;
26
27class X86FastISel : public FastISel {
28 /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
29 /// make the right decision when generating code for different targets.
30 const X86Subtarget *Subtarget;
31
Evan Cheng8b19e562008-09-03 06:44:39 +000032public:
Dan Gohman3df24e62008-09-03 23:12:08 +000033 explicit X86FastISel(MachineFunction &mf,
34 DenseMap<const Value *, unsigned> &vm,
35 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
36 : FastISel(mf, vm, bm) {
Evan Cheng88e30412008-09-03 01:04:47 +000037 Subtarget = &TM.getSubtarget<X86Subtarget>();
38 }
Evan Chengc3f44b02008-09-03 00:03:49 +000039
Dan Gohman3df24e62008-09-03 23:12:08 +000040 virtual bool TargetSelectInstruction(Instruction *I);
Evan Chengc3f44b02008-09-03 00:03:49 +000041
Dan Gohman1adf1b02008-08-19 21:45:35 +000042#include "X86GenFastISel.inc"
Evan Cheng8b19e562008-09-03 06:44:39 +000043
44private:
Dan Gohman3df24e62008-09-03 23:12:08 +000045 bool X86SelectConstAddr(Value *V, unsigned &Op0);
Evan Cheng8b19e562008-09-03 06:44:39 +000046
Dan Gohman3df24e62008-09-03 23:12:08 +000047 bool X86SelectLoad(Instruction *I);
Evan Chengc3f44b02008-09-03 00:03:49 +000048};
Dan Gohman99b21822008-08-28 23:21:34 +000049
Evan Cheng8b19e562008-09-03 06:44:39 +000050/// X86SelectConstAddr - Select and emit code to materialize constant address.
51///
52bool X86FastISel::X86SelectConstAddr(Value *V,
Dan Gohman3df24e62008-09-03 23:12:08 +000053 unsigned &Op0) {
Evan Cheng8b19e562008-09-03 06:44:39 +000054 // FIXME: Only GlobalAddress for now.
55 GlobalValue *GV = dyn_cast<GlobalValue>(V);
56 if (!GV)
57 return false;
58
59 if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) {
60 // Issue load from stub if necessary.
61 unsigned Opc = 0;
62 const TargetRegisterClass *RC = NULL;
63 if (TLI.getPointerTy() == MVT::i32) {
64 Opc = X86::MOV32rm;
65 RC = X86::GR32RegisterClass;
66 } else {
67 Opc = X86::MOV64rm;
68 RC = X86::GR64RegisterClass;
69 }
70 Op0 = createResultReg(RC);
71 X86AddressMode AM;
72 AM.GV = GV;
73 addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
Evan Cheng373d50a2008-09-04 06:18:33 +000074 // Prevent loading GV stub multiple times in same MBB.
75 LocalValueMap[V] = Op0;
Evan Cheng8b19e562008-09-03 06:44:39 +000076 }
77 return true;
78}
79
80/// X86SelectLoad - Select and emit code to implement load instructions.
81///
Dan Gohman3df24e62008-09-03 23:12:08 +000082bool X86FastISel::X86SelectLoad(Instruction *I) {
Evan Cheng8b19e562008-09-03 06:44:39 +000083 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
84 if (VT == MVT::Other || !VT.isSimple())
85 // Unhandled type. Halt "fast" selection and bail.
86 return false;
87 if (VT == MVT::iPTR)
88 // Use pointer type.
89 VT = TLI.getPointerTy();
90 // We only handle legal types. For example, on x86-32 the instruction
91 // selector contains all of the 64-bit instructions from x86-64,
92 // under the assumption that i64 won't be used if the target doesn't
93 // support it.
94 if (!TLI.isTypeLegal(VT))
95 return false;
96
97 Value *V = I->getOperand(0);
Dan Gohman3df24e62008-09-03 23:12:08 +000098 unsigned Op0 = getRegForValue(V);
Evan Cheng8b19e562008-09-03 06:44:39 +000099 if (Op0 == 0) {
100 // Handle constant load address.
Dan Gohman3df24e62008-09-03 23:12:08 +0000101 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0))
Evan Cheng8b19e562008-09-03 06:44:39 +0000102 // Unhandled operand. Halt "fast" selection and bail.
103 return false;
104 }
105
106 // Get opcode and regclass of the output for the given load instruction.
107 unsigned Opc = 0;
108 const TargetRegisterClass *RC = NULL;
109 switch (VT.getSimpleVT()) {
110 default: return false;
111 case MVT::i8:
112 Opc = X86::MOV8rm;
113 RC = X86::GR8RegisterClass;
114 break;
115 case MVT::i16:
116 Opc = X86::MOV16rm;
117 RC = X86::GR16RegisterClass;
118 break;
119 case MVT::i32:
120 Opc = X86::MOV32rm;
121 RC = X86::GR32RegisterClass;
122 break;
123 case MVT::i64:
124 // Must be in x86-64 mode.
125 Opc = X86::MOV64rm;
126 RC = X86::GR64RegisterClass;
127 break;
128 case MVT::f32:
129 if (Subtarget->hasSSE1()) {
130 Opc = X86::MOVSSrm;
131 RC = X86::FR32RegisterClass;
132 } else {
133 Opc = X86::LD_Fp32m;
134 RC = X86::RFP32RegisterClass;
135 }
136 break;
137 case MVT::f64:
138 if (Subtarget->hasSSE2()) {
139 Opc = X86::MOVSDrm;
140 RC = X86::FR64RegisterClass;
141 } else {
142 Opc = X86::LD_Fp64m;
143 RC = X86::RFP64RegisterClass;
144 }
145 break;
146 case MVT::f80:
147 Opc = X86::LD_Fp80m;
148 RC = X86::RFP80RegisterClass;
149 break;
150 }
151
152 unsigned ResultReg = createResultReg(RC);
153 X86AddressMode AM;
154 if (Op0)
155 // Address is in register.
156 AM.Base.Reg = Op0;
157 else
158 AM.GV = cast<GlobalValue>(V);
159 addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
Dan Gohman3df24e62008-09-03 23:12:08 +0000160 UpdateValueMap(I, ResultReg);
Evan Cheng8b19e562008-09-03 06:44:39 +0000161 return true;
162}
163
164
Dan Gohman99b21822008-08-28 23:21:34 +0000165bool
Dan Gohman3df24e62008-09-03 23:12:08 +0000166X86FastISel::TargetSelectInstruction(Instruction *I) {
Dan Gohman99b21822008-08-28 23:21:34 +0000167 switch (I->getOpcode()) {
168 default: break;
Evan Cheng8b19e562008-09-03 06:44:39 +0000169 case Instruction::Load:
Dan Gohman3df24e62008-09-03 23:12:08 +0000170 return X86SelectLoad(I);
Dan Gohman99b21822008-08-28 23:21:34 +0000171 }
172
173 return false;
174}
175
Evan Chengc3f44b02008-09-03 00:03:49 +0000176namespace llvm {
Dan Gohman3df24e62008-09-03 23:12:08 +0000177 llvm::FastISel *X86::createFastISel(MachineFunction &mf,
178 DenseMap<const Value *, unsigned> &vm,
179 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
180 return new X86FastISel(mf, vm, bm);
Evan Chengc3f44b02008-09-03 00:03:49 +0000181 }
Dan Gohman99b21822008-08-28 23:21:34 +0000182}