blob: 9b784b444978b438e648843b6e8e76a4c7d4e4cf [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);
74 }
75 return true;
76}
77
78/// X86SelectLoad - Select and emit code to implement load instructions.
79///
Dan Gohman3df24e62008-09-03 23:12:08 +000080bool X86FastISel::X86SelectLoad(Instruction *I) {
Evan Cheng8b19e562008-09-03 06:44:39 +000081 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
82 if (VT == MVT::Other || !VT.isSimple())
83 // Unhandled type. Halt "fast" selection and bail.
84 return false;
85 if (VT == MVT::iPTR)
86 // Use pointer type.
87 VT = TLI.getPointerTy();
88 // We only handle legal types. For example, on x86-32 the instruction
89 // selector contains all of the 64-bit instructions from x86-64,
90 // under the assumption that i64 won't be used if the target doesn't
91 // support it.
92 if (!TLI.isTypeLegal(VT))
93 return false;
94
95 Value *V = I->getOperand(0);
Dan Gohman3df24e62008-09-03 23:12:08 +000096 unsigned Op0 = getRegForValue(V);
Evan Cheng8b19e562008-09-03 06:44:39 +000097 if (Op0 == 0) {
98 // Handle constant load address.
Dan Gohman3df24e62008-09-03 23:12:08 +000099 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0))
Evan Cheng8b19e562008-09-03 06:44:39 +0000100 // Unhandled operand. Halt "fast" selection and bail.
101 return false;
102 }
103
104 // Get opcode and regclass of the output for the given load instruction.
105 unsigned Opc = 0;
106 const TargetRegisterClass *RC = NULL;
107 switch (VT.getSimpleVT()) {
108 default: return false;
109 case MVT::i8:
110 Opc = X86::MOV8rm;
111 RC = X86::GR8RegisterClass;
112 break;
113 case MVT::i16:
114 Opc = X86::MOV16rm;
115 RC = X86::GR16RegisterClass;
116 break;
117 case MVT::i32:
118 Opc = X86::MOV32rm;
119 RC = X86::GR32RegisterClass;
120 break;
121 case MVT::i64:
122 // Must be in x86-64 mode.
123 Opc = X86::MOV64rm;
124 RC = X86::GR64RegisterClass;
125 break;
126 case MVT::f32:
127 if (Subtarget->hasSSE1()) {
128 Opc = X86::MOVSSrm;
129 RC = X86::FR32RegisterClass;
130 } else {
131 Opc = X86::LD_Fp32m;
132 RC = X86::RFP32RegisterClass;
133 }
134 break;
135 case MVT::f64:
136 if (Subtarget->hasSSE2()) {
137 Opc = X86::MOVSDrm;
138 RC = X86::FR64RegisterClass;
139 } else {
140 Opc = X86::LD_Fp64m;
141 RC = X86::RFP64RegisterClass;
142 }
143 break;
144 case MVT::f80:
145 Opc = X86::LD_Fp80m;
146 RC = X86::RFP80RegisterClass;
147 break;
148 }
149
150 unsigned ResultReg = createResultReg(RC);
151 X86AddressMode AM;
152 if (Op0)
153 // Address is in register.
154 AM.Base.Reg = Op0;
155 else
156 AM.GV = cast<GlobalValue>(V);
157 addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
Dan Gohman3df24e62008-09-03 23:12:08 +0000158 UpdateValueMap(I, ResultReg);
Evan Cheng8b19e562008-09-03 06:44:39 +0000159 return true;
160}
161
162
Dan Gohman99b21822008-08-28 23:21:34 +0000163bool
Dan Gohman3df24e62008-09-03 23:12:08 +0000164X86FastISel::TargetSelectInstruction(Instruction *I) {
Dan Gohman99b21822008-08-28 23:21:34 +0000165 switch (I->getOpcode()) {
166 default: break;
Evan Cheng8b19e562008-09-03 06:44:39 +0000167 case Instruction::Load:
Dan Gohman3df24e62008-09-03 23:12:08 +0000168 return X86SelectLoad(I);
Dan Gohman99b21822008-08-28 23:21:34 +0000169 }
170
171 return false;
172}
173
Evan Chengc3f44b02008-09-03 00:03:49 +0000174namespace llvm {
Dan Gohman3df24e62008-09-03 23:12:08 +0000175 llvm::FastISel *X86::createFastISel(MachineFunction &mf,
176 DenseMap<const Value *, unsigned> &vm,
177 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
178 return new X86FastISel(mf, vm, bm);
Evan Chengc3f44b02008-09-03 00:03:49 +0000179 }
Dan Gohman99b21822008-08-28 23:21:34 +0000180}