blob: cf26238c02399e2bcf68f6f1b3dfef3dd84523aa [file] [log] [blame]
Igor Bregerb4442f32017-02-10 07:05:56 +00001//===- X86LegalizerInfo.cpp --------------------------------------*- C++ -*-==//
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/// \file
10/// This file implements the targeting of the Machinelegalizer class for X86.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
14#include "X86LegalizerInfo.h"
15#include "X86Subtarget.h"
Igor Breger531a2032017-03-26 08:11:12 +000016#include "X86TargetMachine.h"
Igor Bregerb4442f32017-02-10 07:05:56 +000017#include "llvm/CodeGen/ValueTypes.h"
18#include "llvm/IR/DerivedTypes.h"
19#include "llvm/IR/Type.h"
20#include "llvm/Target/TargetOpcodes.h"
21
22using namespace llvm;
Igor Breger321cf3c2017-03-03 08:06:46 +000023using namespace TargetOpcode;
Igor Bregerb4442f32017-02-10 07:05:56 +000024
25#ifndef LLVM_BUILD_GLOBAL_ISEL
26#error "You shouldn't build this"
27#endif
28
Igor Breger531a2032017-03-26 08:11:12 +000029X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
30 const X86TargetMachine &TM)
31 : Subtarget(STI), TM(TM) {
Igor Bregerb4442f32017-02-10 07:05:56 +000032
33 setLegalizerInfo32bit();
34 setLegalizerInfo64bit();
Igor Breger321cf3c2017-03-03 08:06:46 +000035 setLegalizerInfoSSE1();
36 setLegalizerInfoSSE2();
Igor Breger605b9652017-05-08 09:03:37 +000037 setLegalizerInfoSSE41();
38 setLegalizerInfoAVX2();
39 setLegalizerInfoAVX512();
40 setLegalizerInfoAVX512DQ();
41 setLegalizerInfoAVX512BW();
Igor Bregerb4442f32017-02-10 07:05:56 +000042
43 computeTables();
44}
45
46void X86LegalizerInfo::setLegalizerInfo32bit() {
47
Igor Bregera8ba5722017-03-23 15:25:57 +000048 if (Subtarget.is64Bit())
49 return;
50
51 const LLT p0 = LLT::pointer(0, 32);
Igor Breger29537882017-04-07 14:41:59 +000052 const LLT s1 = LLT::scalar(1);
Igor Bregerb4442f32017-02-10 07:05:56 +000053 const LLT s8 = LLT::scalar(8);
54 const LLT s16 = LLT::scalar(16);
55 const LLT s32 = LLT::scalar(32);
Igor Breger29537882017-04-07 14:41:59 +000056 const LLT s64 = LLT::scalar(64);
Igor Bregerb4442f32017-02-10 07:05:56 +000057
Igor Breger605b9652017-05-08 09:03:37 +000058 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL})
Igor Bregera8ba5722017-03-23 15:25:57 +000059 for (auto Ty : {s8, s16, s32})
60 setAction({BinOp, Ty}, Legal);
61
62 for (unsigned MemOp : {G_LOAD, G_STORE}) {
63 for (auto Ty : {s8, s16, s32, p0})
64 setAction({MemOp, Ty}, Legal);
65
66 // And everything's fine in addrspace 0.
67 setAction({MemOp, 1, p0}, Legal);
Igor Bregerf7359d82017-02-22 12:25:09 +000068 }
Igor Breger531a2032017-03-26 08:11:12 +000069
70 // Pointer-handling
71 setAction({G_FRAME_INDEX, p0}, Legal);
Igor Breger29537882017-04-07 14:41:59 +000072
Igor Breger810c6252017-05-08 09:40:43 +000073 setAction({G_GEP, p0}, Legal);
74 setAction({G_GEP, 1, s32}, Legal);
75
76 for (auto Ty : {s1, s8, s16})
77 setAction({G_GEP, 1, Ty}, WidenScalar);
78
Igor Breger29537882017-04-07 14:41:59 +000079 // Constants
80 for (auto Ty : {s8, s16, s32, p0})
81 setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
82
83 setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
84 setAction({TargetOpcode::G_CONSTANT, s64}, NarrowScalar);
Igor Bregerc08a7832017-05-01 06:30:16 +000085
86 // Extensions
87 setAction({G_ZEXT, s32}, Legal);
88 setAction({G_SEXT, s32}, Legal);
89
Igor Bregerfda31e62017-05-10 06:52:58 +000090 for (auto Ty : {s1, s8, s16}) {
Igor Bregerc08a7832017-05-01 06:30:16 +000091 setAction({G_ZEXT, 1, Ty}, Legal);
92 setAction({G_SEXT, 1, Ty}, Legal);
93 }
Igor Bregerc7b59772017-05-11 07:17:40 +000094
95 // Comparison
96 setAction({G_ICMP, s1}, Legal);
97
98 for (auto Ty : {s8, s16, s32, p0})
99 setAction({G_ICMP, 1, Ty}, Legal);
Igor Bregerb4442f32017-02-10 07:05:56 +0000100}
Igor Bregerb4442f32017-02-10 07:05:56 +0000101
Igor Bregerf7359d82017-02-22 12:25:09 +0000102void X86LegalizerInfo::setLegalizerInfo64bit() {
Igor Bregerb4442f32017-02-10 07:05:56 +0000103
104 if (!Subtarget.is64Bit())
105 return;
106
Igor Breger531a2032017-03-26 08:11:12 +0000107 const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8);
Igor Breger29537882017-04-07 14:41:59 +0000108 const LLT s1 = LLT::scalar(1);
Igor Bregera8ba5722017-03-23 15:25:57 +0000109 const LLT s8 = LLT::scalar(8);
110 const LLT s16 = LLT::scalar(16);
111 const LLT s32 = LLT::scalar(32);
Igor Bregerb4442f32017-02-10 07:05:56 +0000112 const LLT s64 = LLT::scalar(64);
113
Igor Breger605b9652017-05-08 09:03:37 +0000114 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL})
Igor Bregera8ba5722017-03-23 15:25:57 +0000115 for (auto Ty : {s8, s16, s32, s64})
116 setAction({BinOp, Ty}, Legal);
117
118 for (unsigned MemOp : {G_LOAD, G_STORE}) {
119 for (auto Ty : {s8, s16, s32, s64, p0})
120 setAction({MemOp, Ty}, Legal);
121
122 // And everything's fine in addrspace 0.
123 setAction({MemOp, 1, p0}, Legal);
124 }
Igor Breger531a2032017-03-26 08:11:12 +0000125
126 // Pointer-handling
127 setAction({G_FRAME_INDEX, p0}, Legal);
Igor Breger29537882017-04-07 14:41:59 +0000128
Igor Breger810c6252017-05-08 09:40:43 +0000129 setAction({G_GEP, p0}, Legal);
130 setAction({G_GEP, 1, s32}, Legal);
131 setAction({G_GEP, 1, s64}, Legal);
132
133 for (auto Ty : {s1, s8, s16})
134 setAction({G_GEP, 1, Ty}, WidenScalar);
135
Igor Breger29537882017-04-07 14:41:59 +0000136 // Constants
137 for (auto Ty : {s8, s16, s32, s64, p0})
138 setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
139
140 setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
Igor Bregerc08a7832017-05-01 06:30:16 +0000141
142 // Extensions
143 for (auto Ty : {s32, s64}) {
144 setAction({G_ZEXT, Ty}, Legal);
145 setAction({G_SEXT, Ty}, Legal);
146 }
147
Igor Bregerfda31e62017-05-10 06:52:58 +0000148 for (auto Ty : {s1, s8, s16, s32}) {
Igor Bregerc08a7832017-05-01 06:30:16 +0000149 setAction({G_ZEXT, 1, Ty}, Legal);
150 setAction({G_SEXT, 1, Ty}, Legal);
151 }
Igor Bregerc7b59772017-05-11 07:17:40 +0000152
153 // Comparison
154 setAction({G_ICMP, s1}, Legal);
155
156 for (auto Ty : {s8, s16, s32, s64, p0})
157 setAction({G_ICMP, 1, Ty}, Legal);
Igor Breger321cf3c2017-03-03 08:06:46 +0000158}
159
160void X86LegalizerInfo::setLegalizerInfoSSE1() {
161 if (!Subtarget.hasSSE1())
162 return;
163
164 const LLT s32 = LLT::scalar(32);
165 const LLT v4s32 = LLT::vector(4, 32);
Igor Bregera8ba5722017-03-23 15:25:57 +0000166 const LLT v2s64 = LLT::vector(2, 64);
Igor Breger321cf3c2017-03-03 08:06:46 +0000167
168 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
169 for (auto Ty : {s32, v4s32})
170 setAction({BinOp, Ty}, Legal);
Igor Bregera8ba5722017-03-23 15:25:57 +0000171
172 for (unsigned MemOp : {G_LOAD, G_STORE})
173 for (auto Ty : {v4s32, v2s64})
174 setAction({MemOp, Ty}, Legal);
Igor Breger321cf3c2017-03-03 08:06:46 +0000175}
176
177void X86LegalizerInfo::setLegalizerInfoSSE2() {
178 if (!Subtarget.hasSSE2())
179 return;
180
181 const LLT s64 = LLT::scalar(64);
Igor Breger605b9652017-05-08 09:03:37 +0000182 const LLT v8s16 = LLT::vector(8, 16);
Igor Breger321cf3c2017-03-03 08:06:46 +0000183 const LLT v4s32 = LLT::vector(4, 32);
184 const LLT v2s64 = LLT::vector(2, 64);
185
186 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
187 for (auto Ty : {s64, v2s64})
188 setAction({BinOp, Ty}, Legal);
189
190 for (unsigned BinOp : {G_ADD, G_SUB})
191 for (auto Ty : {v4s32})
192 setAction({BinOp, Ty}, Legal);
Igor Breger605b9652017-05-08 09:03:37 +0000193
194 setAction({G_MUL, v8s16}, Legal);
195}
196
197void X86LegalizerInfo::setLegalizerInfoSSE41() {
198 if (!Subtarget.hasSSE41())
199 return;
200
201 const LLT v4s32 = LLT::vector(4, 32);
202
203 setAction({G_MUL, v4s32}, Legal);
204}
205
206void X86LegalizerInfo::setLegalizerInfoAVX2() {
207 if (!Subtarget.hasAVX2())
208 return;
209
210 const LLT v16s16 = LLT::vector(16, 16);
211 const LLT v8s32 = LLT::vector(8, 32);
212
213 for (auto Ty : {v16s16, v8s32})
214 setAction({G_MUL, Ty}, Legal);
215}
216
217void X86LegalizerInfo::setLegalizerInfoAVX512() {
218 if (!Subtarget.hasAVX512())
219 return;
220
221 const LLT v16s32 = LLT::vector(16, 32);
222
223 setAction({G_MUL, v16s32}, Legal);
224
225 /************ VLX *******************/
226 if (!Subtarget.hasVLX())
227 return;
228
229 const LLT v4s32 = LLT::vector(4, 32);
230 const LLT v8s32 = LLT::vector(8, 32);
231
232 for (auto Ty : {v4s32, v8s32})
233 setAction({G_MUL, Ty}, Legal);
234}
235
236void X86LegalizerInfo::setLegalizerInfoAVX512DQ() {
237 if (!(Subtarget.hasAVX512() && Subtarget.hasDQI()))
238 return;
239
240 const LLT v8s64 = LLT::vector(8, 64);
241
242 setAction({G_MUL, v8s64}, Legal);
243
244 /************ VLX *******************/
245 if (!Subtarget.hasVLX())
246 return;
247
248 const LLT v2s64 = LLT::vector(2, 64);
249 const LLT v4s64 = LLT::vector(4, 64);
250
251 for (auto Ty : {v2s64, v4s64})
252 setAction({G_MUL, Ty}, Legal);
253}
254
255void X86LegalizerInfo::setLegalizerInfoAVX512BW() {
256 if (!(Subtarget.hasAVX512() && Subtarget.hasBWI()))
257 return;
258
259 const LLT v32s16 = LLT::vector(32, 16);
260
261 setAction({G_MUL, v32s16}, Legal);
262
263 /************ VLX *******************/
264 if (!Subtarget.hasVLX())
265 return;
266
267 const LLT v8s16 = LLT::vector(8, 16);
268 const LLT v16s16 = LLT::vector(16, 16);
269
270 for (auto Ty : {v8s16, v16s16})
271 setAction({G_MUL, Ty}, Legal);
Igor Bregerb4442f32017-02-10 07:05:56 +0000272}