blob: 821f4e29ac71a09f698e5b3b7bfc9529b927c1e2 [file] [log] [blame]
Tom Stellard347ac792015-06-26 21:15:07 +00001//===-- AMDGPUBaseInfo.cpp - AMDGPU Base encoding information--------------===//
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#include "AMDGPUBaseInfo.h"
Tom Stellarde3b5aea2015-12-02 17:00:42 +000010#include "AMDGPU.h"
Sam Kolton1eeb11b2016-09-09 14:44:04 +000011#include "SIDefines.h"
Tom Stellardac00eb52015-12-15 16:26:16 +000012#include "llvm/IR/LLVMContext.h"
13#include "llvm/IR/Function.h"
Tom Stellarde3b5aea2015-12-02 17:00:42 +000014#include "llvm/IR/GlobalValue.h"
Tom Stellarde135ffd2015-09-25 21:41:28 +000015#include "llvm/MC/MCContext.h"
Sam Kolton1eeb11b2016-09-09 14:44:04 +000016#include "llvm/MC/MCInstrInfo.h"
17#include "llvm/MC/MCRegisterInfo.h"
Tom Stellarde135ffd2015-09-25 21:41:28 +000018#include "llvm/MC/MCSectionELF.h"
Tom Stellard2b65ed32015-12-21 18:44:27 +000019#include "llvm/MC/MCSubtargetInfo.h"
Tom Stellard347ac792015-06-26 21:15:07 +000020#include "llvm/MC/SubtargetFeature.h"
21
22#define GET_SUBTARGETINFO_ENUM
23#include "AMDGPUGenSubtargetInfo.inc"
24#undef GET_SUBTARGETINFO_ENUM
25
Tom Stellard2b65ed32015-12-21 18:44:27 +000026#define GET_REGINFO_ENUM
27#include "AMDGPUGenRegisterInfo.inc"
28#undef GET_REGINFO_ENUM
29
Sam Koltona3ec5c12016-10-07 14:46:06 +000030#define GET_INSTRINFO_NAMED_OPS
31#define GET_INSTRINFO_ENUM
32#include "AMDGPUGenInstrInfo.inc"
33#undef GET_INSTRINFO_NAMED_OPS
34#undef GET_INSTRINFO_ENUM
35
Konstantin Zhuravlyovcdd45472016-10-11 18:58:22 +000036namespace {
37
38/// \returns Bit mask for given bit \p Shift and bit \p Width.
39unsigned getBitMask(unsigned Shift, unsigned Width) {
40 return ((1 << Width) - 1) << Shift;
41}
42
43/// \brief Packs \p Src into \p Dst for given bit \p Shift and bit \p Width.
44///
45/// \returns Packed \p Dst.
46unsigned packBits(unsigned Src, unsigned Dst, unsigned Shift, unsigned Width) {
47 Dst &= ~(1 << Shift) & ~getBitMask(Shift, Width);
48 Dst |= (Src << Shift) & getBitMask(Shift, Width);
49 return Dst;
50}
51
52/// \brief Unpacks bits from \p Src for given bit \p Shift and bit \p Width.
53///
54/// \returns Unpacked bits.
55unsigned unpackBits(unsigned Src, unsigned Shift, unsigned Width) {
56 return (Src & getBitMask(Shift, Width)) >> Shift;
57}
58
59/// \returns Vmcnt bit shift.
60unsigned getVmcntBitShift() { return 0; }
61
62/// \returns Vmcnt bit width.
63unsigned getVmcntBitWidth() { return 4; }
64
65/// \returns Expcnt bit shift.
66unsigned getExpcntBitShift() { return 4; }
67
68/// \returns Expcnt bit width.
69unsigned getExpcntBitWidth() { return 3; }
70
71/// \returns Lgkmcnt bit shift.
72unsigned getLgkmcntBitShift() { return 8; }
73
74/// \returns Lgkmcnt bit width.
75unsigned getLgkmcntBitWidth() { return 4; }
76
77} // anonymous namespace
78
Tom Stellard347ac792015-06-26 21:15:07 +000079namespace llvm {
80namespace AMDGPU {
81
82IsaVersion getIsaVersion(const FeatureBitset &Features) {
83
84 if (Features.test(FeatureISAVersion7_0_0))
85 return {7, 0, 0};
86
87 if (Features.test(FeatureISAVersion7_0_1))
88 return {7, 0, 1};
89
Yaxun Liu94add852016-10-26 16:37:56 +000090 if (Features.test(FeatureISAVersion7_0_2))
91 return {7, 0, 2};
92
Tom Stellard347ac792015-06-26 21:15:07 +000093 if (Features.test(FeatureISAVersion8_0_0))
94 return {8, 0, 0};
95
96 if (Features.test(FeatureISAVersion8_0_1))
97 return {8, 0, 1};
98
Changpeng Fang98317d22016-10-11 16:00:47 +000099 if (Features.test(FeatureISAVersion8_0_2))
100 return {8, 0, 2};
101
Changpeng Fangc16be002016-01-13 20:39:25 +0000102 if (Features.test(FeatureISAVersion8_0_3))
103 return {8, 0, 3};
104
Yaxun Liu94add852016-10-26 16:37:56 +0000105 if (Features.test(FeatureISAVersion8_0_4))
106 return {8, 0, 4};
107
108 if (Features.test(FeatureISAVersion8_1_0))
109 return {8, 1, 0};
110
Tom Stellard347ac792015-06-26 21:15:07 +0000111 return {0, 0, 0};
112}
113
Tom Stellardff7416b2015-06-26 21:58:31 +0000114void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header,
115 const FeatureBitset &Features) {
116
117 IsaVersion ISA = getIsaVersion(Features);
118
119 memset(&Header, 0, sizeof(Header));
120
121 Header.amd_kernel_code_version_major = 1;
122 Header.amd_kernel_code_version_minor = 0;
123 Header.amd_machine_kind = 1; // AMD_MACHINE_KIND_AMDGPU
124 Header.amd_machine_version_major = ISA.Major;
125 Header.amd_machine_version_minor = ISA.Minor;
126 Header.amd_machine_version_stepping = ISA.Stepping;
127 Header.kernel_code_entry_byte_offset = sizeof(Header);
128 // wavefront_size is specified as a power of 2: 2^6 = 64 threads.
129 Header.wavefront_size = 6;
Matt Arsenault5d910192017-01-25 20:21:57 +0000130
131 // If the code object does not support indirect functions, then the value must
132 // be 0xffffffff.
133 Header.call_convention = -1;
134
Tom Stellardff7416b2015-06-26 21:58:31 +0000135 // These alignment values are specified in powers of two, so alignment =
136 // 2^n. The minimum alignment is 2^4 = 16.
137 Header.kernarg_segment_alignment = 4;
138 Header.group_segment_alignment = 4;
139 Header.private_segment_alignment = 4;
140}
141
Tom Stellarde135ffd2015-09-25 21:41:28 +0000142MCSection *getHSATextSection(MCContext &Ctx) {
143 return Ctx.getELFSection(".hsatext", ELF::SHT_PROGBITS,
144 ELF::SHF_ALLOC | ELF::SHF_WRITE |
145 ELF::SHF_EXECINSTR |
146 ELF::SHF_AMDGPU_HSA_AGENT |
147 ELF::SHF_AMDGPU_HSA_CODE);
148}
149
Tom Stellard00f2f912015-12-02 19:47:57 +0000150MCSection *getHSADataGlobalAgentSection(MCContext &Ctx) {
151 return Ctx.getELFSection(".hsadata_global_agent", ELF::SHT_PROGBITS,
152 ELF::SHF_ALLOC | ELF::SHF_WRITE |
153 ELF::SHF_AMDGPU_HSA_GLOBAL |
154 ELF::SHF_AMDGPU_HSA_AGENT);
155}
156
157MCSection *getHSADataGlobalProgramSection(MCContext &Ctx) {
158 return Ctx.getELFSection(".hsadata_global_program", ELF::SHT_PROGBITS,
159 ELF::SHF_ALLOC | ELF::SHF_WRITE |
160 ELF::SHF_AMDGPU_HSA_GLOBAL);
161}
162
Tom Stellard9760f032015-12-03 03:34:32 +0000163MCSection *getHSARodataReadonlyAgentSection(MCContext &Ctx) {
164 return Ctx.getELFSection(".hsarodata_readonly_agent", ELF::SHT_PROGBITS,
165 ELF::SHF_ALLOC | ELF::SHF_AMDGPU_HSA_READONLY |
166 ELF::SHF_AMDGPU_HSA_AGENT);
167}
168
Tom Stellarde3b5aea2015-12-02 17:00:42 +0000169bool isGroupSegment(const GlobalValue *GV) {
170 return GV->getType()->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
171}
172
Tom Stellard00f2f912015-12-02 19:47:57 +0000173bool isGlobalSegment(const GlobalValue *GV) {
174 return GV->getType()->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;
175}
176
177bool isReadOnlySegment(const GlobalValue *GV) {
178 return GV->getType()->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS;
179}
180
Konstantin Zhuravlyov08326b62016-10-20 18:12:38 +0000181bool shouldEmitConstantsToTextSection(const Triple &TT) {
182 return TT.getOS() != Triple::AMDHSA;
183}
184
Matt Arsenault83002722016-05-12 02:45:18 +0000185int getIntegerAttribute(const Function &F, StringRef Name, int Default) {
Marek Olsakfccabaf2016-01-13 11:45:36 +0000186 Attribute A = F.getFnAttribute(Name);
Matt Arsenault83002722016-05-12 02:45:18 +0000187 int Result = Default;
Tom Stellardac00eb52015-12-15 16:26:16 +0000188
189 if (A.isStringAttribute()) {
190 StringRef Str = A.getValueAsString();
Marek Olsakfccabaf2016-01-13 11:45:36 +0000191 if (Str.getAsInteger(0, Result)) {
Tom Stellardac00eb52015-12-15 16:26:16 +0000192 LLVMContext &Ctx = F.getContext();
Matt Arsenault83002722016-05-12 02:45:18 +0000193 Ctx.emitError("can't parse integer attribute " + Name);
Tom Stellardac00eb52015-12-15 16:26:16 +0000194 }
195 }
Matt Arsenault83002722016-05-12 02:45:18 +0000196
Marek Olsakfccabaf2016-01-13 11:45:36 +0000197 return Result;
198}
199
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000200std::pair<int, int> getIntegerPairAttribute(const Function &F,
201 StringRef Name,
202 std::pair<int, int> Default,
203 bool OnlyFirstRequired) {
204 Attribute A = F.getFnAttribute(Name);
205 if (!A.isStringAttribute())
206 return Default;
207
208 LLVMContext &Ctx = F.getContext();
209 std::pair<int, int> Ints = Default;
210 std::pair<StringRef, StringRef> Strs = A.getValueAsString().split(',');
211 if (Strs.first.trim().getAsInteger(0, Ints.first)) {
212 Ctx.emitError("can't parse first integer attribute " + Name);
213 return Default;
214 }
215 if (Strs.second.trim().getAsInteger(0, Ints.second)) {
216 if (!OnlyFirstRequired || Strs.second.trim().size()) {
217 Ctx.emitError("can't parse second integer attribute " + Name);
218 return Default;
219 }
220 }
221
222 return Ints;
Tom Stellard79a1fd72016-04-14 16:27:07 +0000223}
224
Konstantin Zhuravlyovcdd45472016-10-11 18:58:22 +0000225unsigned getWaitcntBitMask(IsaVersion Version) {
226 unsigned Vmcnt = getBitMask(getVmcntBitShift(), getVmcntBitWidth());
227 unsigned Expcnt = getBitMask(getExpcntBitShift(), getExpcntBitWidth());
228 unsigned Lgkmcnt = getBitMask(getLgkmcntBitShift(), getLgkmcntBitWidth());
229 return Vmcnt | Expcnt | Lgkmcnt;
Konstantin Zhuravlyov836cbff2016-09-30 17:01:40 +0000230}
231
Konstantin Zhuravlyovcdd45472016-10-11 18:58:22 +0000232unsigned getVmcntBitMask(IsaVersion Version) {
233 return (1 << getVmcntBitWidth()) - 1;
Konstantin Zhuravlyov836cbff2016-09-30 17:01:40 +0000234}
235
Konstantin Zhuravlyovcdd45472016-10-11 18:58:22 +0000236unsigned getExpcntBitMask(IsaVersion Version) {
237 return (1 << getExpcntBitWidth()) - 1;
Konstantin Zhuravlyov836cbff2016-09-30 17:01:40 +0000238}
239
Konstantin Zhuravlyovcdd45472016-10-11 18:58:22 +0000240unsigned getLgkmcntBitMask(IsaVersion Version) {
241 return (1 << getLgkmcntBitWidth()) - 1;
Konstantin Zhuravlyov836cbff2016-09-30 17:01:40 +0000242}
243
Konstantin Zhuravlyovcdd45472016-10-11 18:58:22 +0000244unsigned decodeVmcnt(IsaVersion Version, unsigned Waitcnt) {
245 return unpackBits(Waitcnt, getVmcntBitShift(), getVmcntBitWidth());
Konstantin Zhuravlyov836cbff2016-09-30 17:01:40 +0000246}
247
Konstantin Zhuravlyovcdd45472016-10-11 18:58:22 +0000248unsigned decodeExpcnt(IsaVersion Version, unsigned Waitcnt) {
249 return unpackBits(Waitcnt, getExpcntBitShift(), getExpcntBitWidth());
250}
251
252unsigned decodeLgkmcnt(IsaVersion Version, unsigned Waitcnt) {
253 return unpackBits(Waitcnt, getLgkmcntBitShift(), getLgkmcntBitWidth());
254}
255
256void decodeWaitcnt(IsaVersion Version, unsigned Waitcnt,
257 unsigned &Vmcnt, unsigned &Expcnt, unsigned &Lgkmcnt) {
258 Vmcnt = decodeVmcnt(Version, Waitcnt);
259 Expcnt = decodeExpcnt(Version, Waitcnt);
260 Lgkmcnt = decodeLgkmcnt(Version, Waitcnt);
261}
262
263unsigned encodeVmcnt(IsaVersion Version, unsigned Waitcnt, unsigned Vmcnt) {
264 return packBits(Vmcnt, Waitcnt, getVmcntBitShift(), getVmcntBitWidth());
265}
266
267unsigned encodeExpcnt(IsaVersion Version, unsigned Waitcnt, unsigned Expcnt) {
268 return packBits(Expcnt, Waitcnt, getExpcntBitShift(), getExpcntBitWidth());
269}
270
271unsigned encodeLgkmcnt(IsaVersion Version, unsigned Waitcnt, unsigned Lgkmcnt) {
272 return packBits(Lgkmcnt, Waitcnt, getLgkmcntBitShift(), getLgkmcntBitWidth());
273}
274
275unsigned encodeWaitcnt(IsaVersion Version,
276 unsigned Vmcnt, unsigned Expcnt, unsigned Lgkmcnt) {
Konstantin Zhuravlyov31dbb032017-01-06 17:23:21 +0000277 unsigned Waitcnt = getWaitcntBitMask(Version);
Konstantin Zhuravlyovcdd45472016-10-11 18:58:22 +0000278 Waitcnt = encodeVmcnt(Version, Waitcnt, Vmcnt);
279 Waitcnt = encodeExpcnt(Version, Waitcnt, Expcnt);
280 Waitcnt = encodeLgkmcnt(Version, Waitcnt, Lgkmcnt);
281 return Waitcnt;
Konstantin Zhuravlyov836cbff2016-09-30 17:01:40 +0000282}
283
Marek Olsakfccabaf2016-01-13 11:45:36 +0000284unsigned getInitialPSInputAddr(const Function &F) {
285 return getIntegerAttribute(F, "InitialPSInputAddr", 0);
Tom Stellardac00eb52015-12-15 16:26:16 +0000286}
287
Nicolai Haehnledf3a20c2016-04-06 19:40:20 +0000288bool isShader(CallingConv::ID cc) {
289 switch(cc) {
290 case CallingConv::AMDGPU_VS:
291 case CallingConv::AMDGPU_GS:
292 case CallingConv::AMDGPU_PS:
293 case CallingConv::AMDGPU_CS:
294 return true;
295 default:
296 return false;
297 }
298}
299
300bool isCompute(CallingConv::ID cc) {
301 return !isShader(cc) || cc == CallingConv::AMDGPU_CS;
302}
303
Tom Stellard2b65ed32015-12-21 18:44:27 +0000304bool isSI(const MCSubtargetInfo &STI) {
305 return STI.getFeatureBits()[AMDGPU::FeatureSouthernIslands];
306}
307
308bool isCI(const MCSubtargetInfo &STI) {
309 return STI.getFeatureBits()[AMDGPU::FeatureSeaIslands];
310}
311
312bool isVI(const MCSubtargetInfo &STI) {
313 return STI.getFeatureBits()[AMDGPU::FeatureVolcanicIslands];
314}
315
316unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI) {
317
318 switch(Reg) {
319 default: break;
320 case AMDGPU::FLAT_SCR:
321 assert(!isSI(STI));
322 return isCI(STI) ? AMDGPU::FLAT_SCR_ci : AMDGPU::FLAT_SCR_vi;
323
324 case AMDGPU::FLAT_SCR_LO:
325 assert(!isSI(STI));
326 return isCI(STI) ? AMDGPU::FLAT_SCR_LO_ci : AMDGPU::FLAT_SCR_LO_vi;
327
328 case AMDGPU::FLAT_SCR_HI:
329 assert(!isSI(STI));
330 return isCI(STI) ? AMDGPU::FLAT_SCR_HI_ci : AMDGPU::FLAT_SCR_HI_vi;
331 }
332 return Reg;
333}
334
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000335bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo) {
336 unsigned OpType = Desc.OpInfo[OpNo].OperandType;
Matt Arsenault4bd72362016-12-10 00:39:12 +0000337 return OpType >= AMDGPU::OPERAND_SRC_FIRST &&
338 OpType <= AMDGPU::OPERAND_SRC_LAST;
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000339}
340
341bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo) {
342 unsigned OpType = Desc.OpInfo[OpNo].OperandType;
Matt Arsenault4bd72362016-12-10 00:39:12 +0000343 switch (OpType) {
344 case AMDGPU::OPERAND_REG_IMM_FP32:
345 case AMDGPU::OPERAND_REG_IMM_FP64:
346 case AMDGPU::OPERAND_REG_IMM_FP16:
347 case AMDGPU::OPERAND_REG_INLINE_C_FP32:
348 case AMDGPU::OPERAND_REG_INLINE_C_FP64:
349 case AMDGPU::OPERAND_REG_INLINE_C_FP16:
350 return true;
351 default:
352 return false;
353 }
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000354}
355
356bool isSISrcInlinableOperand(const MCInstrDesc &Desc, unsigned OpNo) {
357 unsigned OpType = Desc.OpInfo[OpNo].OperandType;
Matt Arsenault4bd72362016-12-10 00:39:12 +0000358 return OpType >= AMDGPU::OPERAND_REG_INLINE_C_FIRST &&
359 OpType <= AMDGPU::OPERAND_REG_INLINE_C_LAST;
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000360}
361
Krzysztof Parzyszekc8715502016-10-19 17:40:36 +0000362// Avoid using MCRegisterClass::getSize, since that function will go away
363// (move from MC* level to Target* level). Return size in bits.
Tom Stellardb133fbb2016-10-27 23:05:31 +0000364unsigned getRegBitWidth(unsigned RCID) {
365 switch (RCID) {
Krzysztof Parzyszekc8715502016-10-19 17:40:36 +0000366 case AMDGPU::SGPR_32RegClassID:
367 case AMDGPU::VGPR_32RegClassID:
368 case AMDGPU::VS_32RegClassID:
369 case AMDGPU::SReg_32RegClassID:
370 case AMDGPU::SReg_32_XM0RegClassID:
371 return 32;
372 case AMDGPU::SGPR_64RegClassID:
373 case AMDGPU::VS_64RegClassID:
374 case AMDGPU::SReg_64RegClassID:
375 case AMDGPU::VReg_64RegClassID:
376 return 64;
377 case AMDGPU::VReg_96RegClassID:
378 return 96;
379 case AMDGPU::SGPR_128RegClassID:
380 case AMDGPU::SReg_128RegClassID:
381 case AMDGPU::VReg_128RegClassID:
382 return 128;
383 case AMDGPU::SReg_256RegClassID:
384 case AMDGPU::VReg_256RegClassID:
385 return 256;
386 case AMDGPU::SReg_512RegClassID:
387 case AMDGPU::VReg_512RegClassID:
388 return 512;
389 default:
390 llvm_unreachable("Unexpected register class");
391 }
392}
393
Tom Stellardb133fbb2016-10-27 23:05:31 +0000394unsigned getRegBitWidth(const MCRegisterClass &RC) {
395 return getRegBitWidth(RC.getID());
396}
397
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000398unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc,
399 unsigned OpNo) {
Krzysztof Parzyszekc8715502016-10-19 17:40:36 +0000400 unsigned RCID = Desc.OpInfo[OpNo].RegClass;
401 return getRegBitWidth(MRI->getRegClass(RCID)) / 8;
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000402}
403
Matt Arsenault26faed32016-12-05 22:26:17 +0000404bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi) {
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000405 if (Literal >= -16 && Literal <= 64)
406 return true;
407
Matt Arsenault26faed32016-12-05 22:26:17 +0000408 uint64_t Val = static_cast<uint64_t>(Literal);
409 return (Val == DoubleToBits(0.0)) ||
410 (Val == DoubleToBits(1.0)) ||
411 (Val == DoubleToBits(-1.0)) ||
412 (Val == DoubleToBits(0.5)) ||
413 (Val == DoubleToBits(-0.5)) ||
414 (Val == DoubleToBits(2.0)) ||
415 (Val == DoubleToBits(-2.0)) ||
416 (Val == DoubleToBits(4.0)) ||
417 (Val == DoubleToBits(-4.0)) ||
418 (Val == 0x3fc45f306dc9c882 && HasInv2Pi);
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000419}
420
Matt Arsenault26faed32016-12-05 22:26:17 +0000421bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi) {
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000422 if (Literal >= -16 && Literal <= 64)
423 return true;
424
Matt Arsenault4bd72362016-12-10 00:39:12 +0000425 // The actual type of the operand does not seem to matter as long
426 // as the bits match one of the inline immediate values. For example:
427 //
428 // -nan has the hexadecimal encoding of 0xfffffffe which is -2 in decimal,
429 // so it is a legal inline immediate.
430 //
431 // 1065353216 has the hexadecimal encoding 0x3f800000 which is 1.0f in
432 // floating-point, so it is a legal inline immediate.
433
Matt Arsenault26faed32016-12-05 22:26:17 +0000434 uint32_t Val = static_cast<uint32_t>(Literal);
435 return (Val == FloatToBits(0.0f)) ||
436 (Val == FloatToBits(1.0f)) ||
437 (Val == FloatToBits(-1.0f)) ||
438 (Val == FloatToBits(0.5f)) ||
439 (Val == FloatToBits(-0.5f)) ||
440 (Val == FloatToBits(2.0f)) ||
441 (Val == FloatToBits(-2.0f)) ||
442 (Val == FloatToBits(4.0f)) ||
443 (Val == FloatToBits(-4.0f)) ||
444 (Val == 0x3e22f983 && HasInv2Pi);
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000445}
446
Matt Arsenault4bd72362016-12-10 00:39:12 +0000447bool isInlinableLiteral16(int16_t Literal, bool HasInv2Pi) {
Sam Kolton9dffada2017-01-17 15:26:02 +0000448 if (!HasInv2Pi)
449 return false;
Matt Arsenault4bd72362016-12-10 00:39:12 +0000450
451 if (Literal >= -16 && Literal <= 64)
452 return true;
453
454 uint16_t Val = static_cast<uint16_t>(Literal);
455 return Val == 0x3C00 || // 1.0
456 Val == 0xBC00 || // -1.0
457 Val == 0x3800 || // 0.5
458 Val == 0xB800 || // -0.5
459 Val == 0x4000 || // 2.0
460 Val == 0xC000 || // -2.0
461 Val == 0x4400 || // 4.0
462 Val == 0xC400 || // -4.0
463 Val == 0x3118; // 1/2pi
464}
Sam Kolton1eeb11b2016-09-09 14:44:04 +0000465
Tom Stellard347ac792015-06-26 21:15:07 +0000466} // End namespace AMDGPU
467} // End namespace llvm