X86LegalizerInfo.cpp revision 318681
1317017Sdim//===- X86LegalizerInfo.cpp --------------------------------------*- C++ -*-==// 2317017Sdim// 3317017Sdim// The LLVM Compiler Infrastructure 4317017Sdim// 5317017Sdim// This file is distributed under the University of Illinois Open Source 6317017Sdim// License. See LICENSE.TXT for details. 7317017Sdim// 8317017Sdim//===----------------------------------------------------------------------===// 9317017Sdim/// \file 10317017Sdim/// This file implements the targeting of the Machinelegalizer class for X86. 11317017Sdim/// \todo This should be generated by TableGen. 12317017Sdim//===----------------------------------------------------------------------===// 13317017Sdim 14317017Sdim#include "X86LegalizerInfo.h" 15317017Sdim#include "X86Subtarget.h" 16317017Sdim#include "X86TargetMachine.h" 17317017Sdim#include "llvm/CodeGen/ValueTypes.h" 18317017Sdim#include "llvm/IR/DerivedTypes.h" 19317017Sdim#include "llvm/IR/Type.h" 20317017Sdim#include "llvm/Target/TargetOpcodes.h" 21317017Sdim 22317017Sdimusing namespace llvm; 23317017Sdimusing namespace TargetOpcode; 24317017Sdim 25317017Sdim#ifndef LLVM_BUILD_GLOBAL_ISEL 26317017Sdim#error "You shouldn't build this" 27317017Sdim#endif 28317017Sdim 29317017SdimX86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, 30317017Sdim const X86TargetMachine &TM) 31317017Sdim : Subtarget(STI), TM(TM) { 32317017Sdim 33317017Sdim setLegalizerInfo32bit(); 34317017Sdim setLegalizerInfo64bit(); 35317017Sdim setLegalizerInfoSSE1(); 36317017Sdim setLegalizerInfoSSE2(); 37317969Sdim setLegalizerInfoSSE41(); 38317969Sdim setLegalizerInfoAVX2(); 39317969Sdim setLegalizerInfoAVX512(); 40317969Sdim setLegalizerInfoAVX512DQ(); 41317969Sdim setLegalizerInfoAVX512BW(); 42317017Sdim 43317017Sdim computeTables(); 44317017Sdim} 45317017Sdim 46317017Sdimvoid X86LegalizerInfo::setLegalizerInfo32bit() { 47317017Sdim 48317017Sdim if (Subtarget.is64Bit()) 49317017Sdim return; 50317017Sdim 51317017Sdim const LLT p0 = LLT::pointer(0, 32); 52317017Sdim const LLT s1 = LLT::scalar(1); 53317017Sdim const LLT s8 = LLT::scalar(8); 54317017Sdim const LLT s16 = LLT::scalar(16); 55317017Sdim const LLT s32 = LLT::scalar(32); 56317017Sdim const LLT s64 = LLT::scalar(64); 57317017Sdim 58317969Sdim for (unsigned BinOp : {G_ADD, G_SUB, G_MUL}) 59317017Sdim for (auto Ty : {s8, s16, s32}) 60317017Sdim setAction({BinOp, Ty}, Legal); 61317017Sdim 62318477Sdim for (unsigned Op : {G_UADDE}) { 63318477Sdim setAction({Op, s32}, Legal); 64318477Sdim setAction({Op, 1, s1}, Legal); 65318477Sdim } 66318477Sdim 67317017Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) { 68317017Sdim for (auto Ty : {s8, s16, s32, p0}) 69317017Sdim setAction({MemOp, Ty}, Legal); 70317017Sdim 71317017Sdim // And everything's fine in addrspace 0. 72317017Sdim setAction({MemOp, 1, p0}, Legal); 73317017Sdim } 74317017Sdim 75317017Sdim // Pointer-handling 76317017Sdim setAction({G_FRAME_INDEX, p0}, Legal); 77317017Sdim 78317969Sdim setAction({G_GEP, p0}, Legal); 79317969Sdim setAction({G_GEP, 1, s32}, Legal); 80317969Sdim 81317969Sdim for (auto Ty : {s1, s8, s16}) 82317969Sdim setAction({G_GEP, 1, Ty}, WidenScalar); 83317969Sdim 84317017Sdim // Constants 85317017Sdim for (auto Ty : {s8, s16, s32, p0}) 86317017Sdim setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); 87317017Sdim 88317017Sdim setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar); 89317017Sdim setAction({TargetOpcode::G_CONSTANT, s64}, NarrowScalar); 90317778Sdim 91317778Sdim // Extensions 92317778Sdim setAction({G_ZEXT, s32}, Legal); 93317778Sdim setAction({G_SEXT, s32}, Legal); 94317778Sdim 95318384Sdim for (auto Ty : {s1, s8, s16}) { 96317778Sdim setAction({G_ZEXT, 1, Ty}, Legal); 97317778Sdim setAction({G_SEXT, 1, Ty}, Legal); 98317778Sdim } 99318384Sdim 100318384Sdim // Comparison 101318384Sdim setAction({G_ICMP, s1}, Legal); 102318384Sdim 103318384Sdim for (auto Ty : {s8, s16, s32, p0}) 104318384Sdim setAction({G_ICMP, 1, Ty}, Legal); 105317017Sdim} 106317017Sdim 107317017Sdimvoid X86LegalizerInfo::setLegalizerInfo64bit() { 108317017Sdim 109317017Sdim if (!Subtarget.is64Bit()) 110317017Sdim return; 111317017Sdim 112317017Sdim const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8); 113317017Sdim const LLT s1 = LLT::scalar(1); 114317017Sdim const LLT s8 = LLT::scalar(8); 115317017Sdim const LLT s16 = LLT::scalar(16); 116317017Sdim const LLT s32 = LLT::scalar(32); 117317017Sdim const LLT s64 = LLT::scalar(64); 118317017Sdim 119317969Sdim for (unsigned BinOp : {G_ADD, G_SUB, G_MUL}) 120317017Sdim for (auto Ty : {s8, s16, s32, s64}) 121317017Sdim setAction({BinOp, Ty}, Legal); 122317017Sdim 123317017Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) { 124317017Sdim for (auto Ty : {s8, s16, s32, s64, p0}) 125317017Sdim setAction({MemOp, Ty}, Legal); 126317017Sdim 127317017Sdim // And everything's fine in addrspace 0. 128317017Sdim setAction({MemOp, 1, p0}, Legal); 129317017Sdim } 130317017Sdim 131317017Sdim // Pointer-handling 132317017Sdim setAction({G_FRAME_INDEX, p0}, Legal); 133317017Sdim 134317969Sdim setAction({G_GEP, p0}, Legal); 135317969Sdim setAction({G_GEP, 1, s32}, Legal); 136317969Sdim setAction({G_GEP, 1, s64}, Legal); 137317969Sdim 138317969Sdim for (auto Ty : {s1, s8, s16}) 139317969Sdim setAction({G_GEP, 1, Ty}, WidenScalar); 140317969Sdim 141317017Sdim // Constants 142317017Sdim for (auto Ty : {s8, s16, s32, s64, p0}) 143317017Sdim setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); 144317017Sdim 145317017Sdim setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar); 146317778Sdim 147317778Sdim // Extensions 148317778Sdim for (auto Ty : {s32, s64}) { 149317778Sdim setAction({G_ZEXT, Ty}, Legal); 150317778Sdim setAction({G_SEXT, Ty}, Legal); 151317778Sdim } 152317778Sdim 153318384Sdim for (auto Ty : {s1, s8, s16, s32}) { 154317778Sdim setAction({G_ZEXT, 1, Ty}, Legal); 155317778Sdim setAction({G_SEXT, 1, Ty}, Legal); 156317778Sdim } 157318384Sdim 158318384Sdim // Comparison 159318384Sdim setAction({G_ICMP, s1}, Legal); 160318384Sdim 161318384Sdim for (auto Ty : {s8, s16, s32, s64, p0}) 162318384Sdim setAction({G_ICMP, 1, Ty}, Legal); 163317017Sdim} 164317017Sdim 165317017Sdimvoid X86LegalizerInfo::setLegalizerInfoSSE1() { 166317017Sdim if (!Subtarget.hasSSE1()) 167317017Sdim return; 168317017Sdim 169317017Sdim const LLT s32 = LLT::scalar(32); 170317017Sdim const LLT v4s32 = LLT::vector(4, 32); 171317017Sdim const LLT v2s64 = LLT::vector(2, 64); 172317017Sdim 173317017Sdim for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 174317017Sdim for (auto Ty : {s32, v4s32}) 175317017Sdim setAction({BinOp, Ty}, Legal); 176317017Sdim 177317017Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) 178317017Sdim for (auto Ty : {v4s32, v2s64}) 179317017Sdim setAction({MemOp, Ty}, Legal); 180317017Sdim} 181317017Sdim 182317017Sdimvoid X86LegalizerInfo::setLegalizerInfoSSE2() { 183317017Sdim if (!Subtarget.hasSSE2()) 184317017Sdim return; 185317017Sdim 186317017Sdim const LLT s64 = LLT::scalar(64); 187318681Sdim const LLT v16s8 = LLT::vector(16, 8); 188317969Sdim const LLT v8s16 = LLT::vector(8, 16); 189317017Sdim const LLT v4s32 = LLT::vector(4, 32); 190317017Sdim const LLT v2s64 = LLT::vector(2, 64); 191317017Sdim 192317017Sdim for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 193317017Sdim for (auto Ty : {s64, v2s64}) 194317017Sdim setAction({BinOp, Ty}, Legal); 195317017Sdim 196317017Sdim for (unsigned BinOp : {G_ADD, G_SUB}) 197318681Sdim for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) 198317017Sdim setAction({BinOp, Ty}, Legal); 199317969Sdim 200317969Sdim setAction({G_MUL, v8s16}, Legal); 201317017Sdim} 202317969Sdim 203317969Sdimvoid X86LegalizerInfo::setLegalizerInfoSSE41() { 204317969Sdim if (!Subtarget.hasSSE41()) 205317969Sdim return; 206317969Sdim 207317969Sdim const LLT v4s32 = LLT::vector(4, 32); 208317969Sdim 209317969Sdim setAction({G_MUL, v4s32}, Legal); 210317969Sdim} 211317969Sdim 212317969Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX2() { 213317969Sdim if (!Subtarget.hasAVX2()) 214317969Sdim return; 215317969Sdim 216318681Sdim const LLT v32s8 = LLT::vector(32, 8); 217317969Sdim const LLT v16s16 = LLT::vector(16, 16); 218317969Sdim const LLT v8s32 = LLT::vector(8, 32); 219318681Sdim const LLT v4s64 = LLT::vector(4, 64); 220317969Sdim 221318681Sdim for (unsigned BinOp : {G_ADD, G_SUB}) 222318681Sdim for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) 223318681Sdim setAction({BinOp, Ty}, Legal); 224318681Sdim 225317969Sdim for (auto Ty : {v16s16, v8s32}) 226317969Sdim setAction({G_MUL, Ty}, Legal); 227317969Sdim} 228317969Sdim 229317969Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX512() { 230317969Sdim if (!Subtarget.hasAVX512()) 231317969Sdim return; 232317969Sdim 233317969Sdim const LLT v16s32 = LLT::vector(16, 32); 234318681Sdim const LLT v8s64 = LLT::vector(8, 64); 235317969Sdim 236318681Sdim for (unsigned BinOp : {G_ADD, G_SUB}) 237318681Sdim for (auto Ty : {v16s32, v8s64}) 238318681Sdim setAction({BinOp, Ty}, Legal); 239318681Sdim 240317969Sdim setAction({G_MUL, v16s32}, Legal); 241317969Sdim 242317969Sdim /************ VLX *******************/ 243317969Sdim if (!Subtarget.hasVLX()) 244317969Sdim return; 245317969Sdim 246317969Sdim const LLT v4s32 = LLT::vector(4, 32); 247317969Sdim const LLT v8s32 = LLT::vector(8, 32); 248317969Sdim 249317969Sdim for (auto Ty : {v4s32, v8s32}) 250317969Sdim setAction({G_MUL, Ty}, Legal); 251317969Sdim} 252317969Sdim 253317969Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX512DQ() { 254317969Sdim if (!(Subtarget.hasAVX512() && Subtarget.hasDQI())) 255317969Sdim return; 256317969Sdim 257317969Sdim const LLT v8s64 = LLT::vector(8, 64); 258317969Sdim 259317969Sdim setAction({G_MUL, v8s64}, Legal); 260317969Sdim 261317969Sdim /************ VLX *******************/ 262317969Sdim if (!Subtarget.hasVLX()) 263317969Sdim return; 264317969Sdim 265317969Sdim const LLT v2s64 = LLT::vector(2, 64); 266317969Sdim const LLT v4s64 = LLT::vector(4, 64); 267317969Sdim 268317969Sdim for (auto Ty : {v2s64, v4s64}) 269317969Sdim setAction({G_MUL, Ty}, Legal); 270317969Sdim} 271317969Sdim 272317969Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX512BW() { 273317969Sdim if (!(Subtarget.hasAVX512() && Subtarget.hasBWI())) 274317969Sdim return; 275317969Sdim 276318681Sdim const LLT v64s8 = LLT::vector(64, 8); 277317969Sdim const LLT v32s16 = LLT::vector(32, 16); 278317969Sdim 279318681Sdim for (unsigned BinOp : {G_ADD, G_SUB}) 280318681Sdim for (auto Ty : {v64s8, v32s16}) 281318681Sdim setAction({BinOp, Ty}, Legal); 282318681Sdim 283317969Sdim setAction({G_MUL, v32s16}, Legal); 284317969Sdim 285317969Sdim /************ VLX *******************/ 286317969Sdim if (!Subtarget.hasVLX()) 287317969Sdim return; 288317969Sdim 289317969Sdim const LLT v8s16 = LLT::vector(8, 16); 290317969Sdim const LLT v16s16 = LLT::vector(16, 16); 291317969Sdim 292317969Sdim for (auto Ty : {v8s16, v16s16}) 293317969Sdim setAction({G_MUL, Ty}, Legal); 294317969Sdim} 295