blob: 658b65dba733ae5957a0384ec998be628db8352f [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:
Evan Cheng88e30412008-09-03 01:04:47 +000033 explicit X86FastISel(MachineFunction &mf) : FastISel(mf) {
34 Subtarget = &TM.getSubtarget<X86Subtarget>();
35 }
Evan Chengc3f44b02008-09-03 00:03:49 +000036
37 virtual bool
38 TargetSelectInstruction(Instruction *I,
39 DenseMap<const Value *, unsigned> &ValueMap,
40 DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap,
41 MachineBasicBlock *MBB);
42
Dan Gohman1adf1b02008-08-19 21:45:35 +000043#include "X86GenFastISel.inc"
Evan Cheng8b19e562008-09-03 06:44:39 +000044
45private:
46 bool X86SelectConstAddr(Value *V,
47 DenseMap<const Value *, unsigned> &ValueMap,
48 MachineBasicBlock *MBB, unsigned &Op0);
49
50 bool X86SelectLoad(Instruction *I,
51 DenseMap<const Value *, unsigned> &ValueMap,
52 MachineBasicBlock *MBB);
Evan Chengc3f44b02008-09-03 00:03:49 +000053};
Dan Gohman99b21822008-08-28 23:21:34 +000054
Evan Cheng8b19e562008-09-03 06:44:39 +000055/// X86SelectConstAddr - Select and emit code to materialize constant address.
56///
57bool X86FastISel::X86SelectConstAddr(Value *V,
58 DenseMap<const Value *, unsigned> &ValueMap,
59 MachineBasicBlock *MBB,
60 unsigned &Op0) {
61 // FIXME: Only GlobalAddress for now.
62 GlobalValue *GV = dyn_cast<GlobalValue>(V);
63 if (!GV)
64 return false;
65
66 if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) {
67 // Issue load from stub if necessary.
68 unsigned Opc = 0;
69 const TargetRegisterClass *RC = NULL;
70 if (TLI.getPointerTy() == MVT::i32) {
71 Opc = X86::MOV32rm;
72 RC = X86::GR32RegisterClass;
73 } else {
74 Opc = X86::MOV64rm;
75 RC = X86::GR64RegisterClass;
76 }
77 Op0 = createResultReg(RC);
78 X86AddressMode AM;
79 AM.GV = GV;
80 addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
81 }
82 return true;
83}
84
85/// X86SelectLoad - Select and emit code to implement load instructions.
86///
87bool X86FastISel::X86SelectLoad(Instruction *I,
88 DenseMap<const Value *, unsigned> &ValueMap,
89 MachineBasicBlock *MBB) {
90 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
91 if (VT == MVT::Other || !VT.isSimple())
92 // Unhandled type. Halt "fast" selection and bail.
93 return false;
94 if (VT == MVT::iPTR)
95 // Use pointer type.
96 VT = TLI.getPointerTy();
97 // We only handle legal types. For example, on x86-32 the instruction
98 // selector contains all of the 64-bit instructions from x86-64,
99 // under the assumption that i64 won't be used if the target doesn't
100 // support it.
101 if (!TLI.isTypeLegal(VT))
102 return false;
103
104 Value *V = I->getOperand(0);
105 unsigned Op0 = getRegForValue(V, ValueMap);
106 if (Op0 == 0) {
107 // Handle constant load address.
108 if (!isa<Constant>(V) || !X86SelectConstAddr(V, ValueMap, MBB, Op0))
109 // Unhandled operand. Halt "fast" selection and bail.
110 return false;
111 }
112
113 // Get opcode and regclass of the output for the given load instruction.
114 unsigned Opc = 0;
115 const TargetRegisterClass *RC = NULL;
116 switch (VT.getSimpleVT()) {
117 default: return false;
118 case MVT::i8:
119 Opc = X86::MOV8rm;
120 RC = X86::GR8RegisterClass;
121 break;
122 case MVT::i16:
123 Opc = X86::MOV16rm;
124 RC = X86::GR16RegisterClass;
125 break;
126 case MVT::i32:
127 Opc = X86::MOV32rm;
128 RC = X86::GR32RegisterClass;
129 break;
130 case MVT::i64:
131 // Must be in x86-64 mode.
132 Opc = X86::MOV64rm;
133 RC = X86::GR64RegisterClass;
134 break;
135 case MVT::f32:
136 if (Subtarget->hasSSE1()) {
137 Opc = X86::MOVSSrm;
138 RC = X86::FR32RegisterClass;
139 } else {
140 Opc = X86::LD_Fp32m;
141 RC = X86::RFP32RegisterClass;
142 }
143 break;
144 case MVT::f64:
145 if (Subtarget->hasSSE2()) {
146 Opc = X86::MOVSDrm;
147 RC = X86::FR64RegisterClass;
148 } else {
149 Opc = X86::LD_Fp64m;
150 RC = X86::RFP64RegisterClass;
151 }
152 break;
153 case MVT::f80:
154 Opc = X86::LD_Fp80m;
155 RC = X86::RFP80RegisterClass;
156 break;
157 }
158
159 unsigned ResultReg = createResultReg(RC);
160 X86AddressMode AM;
161 if (Op0)
162 // Address is in register.
163 AM.Base.Reg = Op0;
164 else
165 AM.GV = cast<GlobalValue>(V);
166 addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
167 UpdateValueMap(I, ResultReg, ValueMap);
168 return true;
169}
170
171
Dan Gohman99b21822008-08-28 23:21:34 +0000172bool
Evan Chengc3f44b02008-09-03 00:03:49 +0000173X86FastISel::TargetSelectInstruction(Instruction *I,
Dan Gohman99b21822008-08-28 23:21:34 +0000174 DenseMap<const Value *, unsigned> &ValueMap,
175 DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap,
176 MachineBasicBlock *MBB) {
177 switch (I->getOpcode()) {
178 default: break;
Evan Cheng8b19e562008-09-03 06:44:39 +0000179 case Instruction::Load:
180 return X86SelectLoad(I, ValueMap, MBB);
Dan Gohman99b21822008-08-28 23:21:34 +0000181 }
182
183 return false;
184}
185
Evan Chengc3f44b02008-09-03 00:03:49 +0000186namespace llvm {
187 llvm::FastISel *X86::createFastISel(MachineFunction &mf) {
188 return new X86FastISel(mf);
189 }
Dan Gohman99b21822008-08-28 23:21:34 +0000190}