1 //===- X86LegalizerInfo.cpp --------------------------------------*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file implements the targeting of the Machinelegalizer class for X86.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
14 #include "X86LegalizerInfo.h"
15 #include "X86Subtarget.h"
16 #include "X86TargetMachine.h"
17 #include "llvm/CodeGen/ValueTypes.h"
18 #include "llvm/IR/DerivedTypes.h"
19 #include "llvm/IR/Type.h"
20 #include "llvm/Target/TargetOpcodes.h"
23 using namespace TargetOpcode;
25 #ifndef LLVM_BUILD_GLOBAL_ISEL
26 #error "You shouldn't build this"
29 X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
30 const X86TargetMachine &TM)
31 : Subtarget(STI), TM(TM) {
33 setLegalizerInfo32bit();
34 setLegalizerInfo64bit();
35 setLegalizerInfoSSE1();
36 setLegalizerInfoSSE2();
37 setLegalizerInfoSSE41();
38 setLegalizerInfoAVX2();
39 setLegalizerInfoAVX512();
40 setLegalizerInfoAVX512DQ();
41 setLegalizerInfoAVX512BW();
46 void X86LegalizerInfo::setLegalizerInfo32bit() {
48 if (Subtarget.is64Bit())
51 const LLT p0 = LLT::pointer(0, 32);
52 const LLT s1 = LLT::scalar(1);
53 const LLT s8 = LLT::scalar(8);
54 const LLT s16 = LLT::scalar(16);
55 const LLT s32 = LLT::scalar(32);
56 const LLT s64 = LLT::scalar(64);
58 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL})
59 for (auto Ty : {s8, s16, s32})
60 setAction({BinOp, Ty}, Legal);
62 for (unsigned MemOp : {G_LOAD, G_STORE}) {
63 for (auto Ty : {s8, s16, s32, p0})
64 setAction({MemOp, Ty}, Legal);
66 // And everything's fine in addrspace 0.
67 setAction({MemOp, 1, p0}, Legal);
71 setAction({G_FRAME_INDEX, p0}, Legal);
73 setAction({G_GEP, p0}, Legal);
74 setAction({G_GEP, 1, s32}, Legal);
76 for (auto Ty : {s1, s8, s16})
77 setAction({G_GEP, 1, Ty}, WidenScalar);
80 for (auto Ty : {s8, s16, s32, p0})
81 setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
83 setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
84 setAction({TargetOpcode::G_CONSTANT, s64}, NarrowScalar);
87 setAction({G_ZEXT, s32}, Legal);
88 setAction({G_SEXT, s32}, Legal);
90 for (auto Ty : {s8, s16}) {
91 setAction({G_ZEXT, 1, Ty}, Legal);
92 setAction({G_SEXT, 1, Ty}, Legal);
96 void X86LegalizerInfo::setLegalizerInfo64bit() {
98 if (!Subtarget.is64Bit())
101 const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8);
102 const LLT s1 = LLT::scalar(1);
103 const LLT s8 = LLT::scalar(8);
104 const LLT s16 = LLT::scalar(16);
105 const LLT s32 = LLT::scalar(32);
106 const LLT s64 = LLT::scalar(64);
108 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL})
109 for (auto Ty : {s8, s16, s32, s64})
110 setAction({BinOp, Ty}, Legal);
112 for (unsigned MemOp : {G_LOAD, G_STORE}) {
113 for (auto Ty : {s8, s16, s32, s64, p0})
114 setAction({MemOp, Ty}, Legal);
116 // And everything's fine in addrspace 0.
117 setAction({MemOp, 1, p0}, Legal);
121 setAction({G_FRAME_INDEX, p0}, Legal);
123 setAction({G_GEP, p0}, Legal);
124 setAction({G_GEP, 1, s32}, Legal);
125 setAction({G_GEP, 1, s64}, Legal);
127 for (auto Ty : {s1, s8, s16})
128 setAction({G_GEP, 1, Ty}, WidenScalar);
131 for (auto Ty : {s8, s16, s32, s64, p0})
132 setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
134 setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
137 for (auto Ty : {s32, s64}) {
138 setAction({G_ZEXT, Ty}, Legal);
139 setAction({G_SEXT, Ty}, Legal);
142 for (auto Ty : {s8, s16, s32}) {
143 setAction({G_ZEXT, 1, Ty}, Legal);
144 setAction({G_SEXT, 1, Ty}, Legal);
148 void X86LegalizerInfo::setLegalizerInfoSSE1() {
149 if (!Subtarget.hasSSE1())
152 const LLT s32 = LLT::scalar(32);
153 const LLT v4s32 = LLT::vector(4, 32);
154 const LLT v2s64 = LLT::vector(2, 64);
156 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
157 for (auto Ty : {s32, v4s32})
158 setAction({BinOp, Ty}, Legal);
160 for (unsigned MemOp : {G_LOAD, G_STORE})
161 for (auto Ty : {v4s32, v2s64})
162 setAction({MemOp, Ty}, Legal);
165 void X86LegalizerInfo::setLegalizerInfoSSE2() {
166 if (!Subtarget.hasSSE2())
169 const LLT s64 = LLT::scalar(64);
170 const LLT v8s16 = LLT::vector(8, 16);
171 const LLT v4s32 = LLT::vector(4, 32);
172 const LLT v2s64 = LLT::vector(2, 64);
174 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
175 for (auto Ty : {s64, v2s64})
176 setAction({BinOp, Ty}, Legal);
178 for (unsigned BinOp : {G_ADD, G_SUB})
179 for (auto Ty : {v4s32})
180 setAction({BinOp, Ty}, Legal);
182 setAction({G_MUL, v8s16}, Legal);
185 void X86LegalizerInfo::setLegalizerInfoSSE41() {
186 if (!Subtarget.hasSSE41())
189 const LLT v4s32 = LLT::vector(4, 32);
191 setAction({G_MUL, v4s32}, Legal);
194 void X86LegalizerInfo::setLegalizerInfoAVX2() {
195 if (!Subtarget.hasAVX2())
198 const LLT v16s16 = LLT::vector(16, 16);
199 const LLT v8s32 = LLT::vector(8, 32);
201 for (auto Ty : {v16s16, v8s32})
202 setAction({G_MUL, Ty}, Legal);
205 void X86LegalizerInfo::setLegalizerInfoAVX512() {
206 if (!Subtarget.hasAVX512())
209 const LLT v16s32 = LLT::vector(16, 32);
211 setAction({G_MUL, v16s32}, Legal);
213 /************ VLX *******************/
214 if (!Subtarget.hasVLX())
217 const LLT v4s32 = LLT::vector(4, 32);
218 const LLT v8s32 = LLT::vector(8, 32);
220 for (auto Ty : {v4s32, v8s32})
221 setAction({G_MUL, Ty}, Legal);
224 void X86LegalizerInfo::setLegalizerInfoAVX512DQ() {
225 if (!(Subtarget.hasAVX512() && Subtarget.hasDQI()))
228 const LLT v8s64 = LLT::vector(8, 64);
230 setAction({G_MUL, v8s64}, Legal);
232 /************ VLX *******************/
233 if (!Subtarget.hasVLX())
236 const LLT v2s64 = LLT::vector(2, 64);
237 const LLT v4s64 = LLT::vector(4, 64);
239 for (auto Ty : {v2s64, v4s64})
240 setAction({G_MUL, Ty}, Legal);
243 void X86LegalizerInfo::setLegalizerInfoAVX512BW() {
244 if (!(Subtarget.hasAVX512() && Subtarget.hasBWI()))
247 const LLT v32s16 = LLT::vector(32, 16);
249 setAction({G_MUL, v32s16}, Legal);
251 /************ VLX *******************/
252 if (!Subtarget.hasVLX())
255 const LLT v8s16 = LLT::vector(8, 16);
256 const LLT v16s16 = LLT::vector(16, 16);
258 for (auto Ty : {v8s16, v16s16})
259 setAction({G_MUL, Ty}, Legal);