1 //===-- VE.h - Top-level interface for VE representation --------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the entry points for global functions defined in the LLVM
10 // VE back-end.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_TARGET_VE_VE_H
15 #define LLVM_LIB_TARGET_VE_VE_H
16
17 #include "MCTargetDesc/VEMCTargetDesc.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Target/TargetMachine.h"
21
22 namespace llvm {
23 class FunctionPass;
24 class VETargetMachine;
25 class AsmPrinter;
26 class MCInst;
27 class MachineInstr;
28
29 FunctionPass *createVEISelDag(VETargetMachine &TM);
30 FunctionPass *createLVLGenPass();
31
32 void LowerVEMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
33 AsmPrinter &AP);
34 } // namespace llvm
35
36 namespace llvm {
37 // Enums corresponding to VE condition codes, both icc's and fcc's. These
38 // values must be kept in sync with the ones in the .td file.
39 namespace VECC {
40 enum CondCode {
41 // Integer comparison
42 CC_IG = 0, // Greater
43 CC_IL = 1, // Less
44 CC_INE = 2, // Not Equal
45 CC_IEQ = 3, // Equal
46 CC_IGE = 4, // Greater or Equal
47 CC_ILE = 5, // Less or Equal
48
49 // Floating point comparison
50 CC_AF = 0 + 6, // Never
51 CC_G = 1 + 6, // Greater
52 CC_L = 2 + 6, // Less
53 CC_NE = 3 + 6, // Not Equal
54 CC_EQ = 4 + 6, // Equal
55 CC_GE = 5 + 6, // Greater or Equal
56 CC_LE = 6 + 6, // Less or Equal
57 CC_NUM = 7 + 6, // Number
58 CC_NAN = 8 + 6, // NaN
59 CC_GNAN = 9 + 6, // Greater or NaN
60 CC_LNAN = 10 + 6, // Less or NaN
61 CC_NENAN = 11 + 6, // Not Equal or NaN
62 CC_EQNAN = 12 + 6, // Equal or NaN
63 CC_GENAN = 13 + 6, // Greater or Equal or NaN
64 CC_LENAN = 14 + 6, // Less or Equal or NaN
65 CC_AT = 15 + 6, // Always
66 UNKNOWN
67 };
68 }
69 // Enums corresponding to VE Rounding Mode. These values must be kept in
70 // sync with the ones in the .td file.
71 namespace VERD {
72 enum RoundingMode {
73 RD_NONE = 0, // According to PSW
74 RD_RZ = 8, // Round toward Zero
75 RD_RP = 9, // Round toward Plus infinity
76 RD_RM = 10, // Round toward Minus infinity
77 RD_RN = 11, // Round to Nearest (ties to Even)
78 RD_RA = 12, // Round to Nearest (ties to Away)
79 UNKNOWN
80 };
81 }
82
VECondCodeToString(VECC::CondCode CC)83 inline static const char *VECondCodeToString(VECC::CondCode CC) {
84 switch (CC) {
85 case VECC::CC_IG: return "gt";
86 case VECC::CC_IL: return "lt";
87 case VECC::CC_INE: return "ne";
88 case VECC::CC_IEQ: return "eq";
89 case VECC::CC_IGE: return "ge";
90 case VECC::CC_ILE: return "le";
91 case VECC::CC_AF: return "af";
92 case VECC::CC_G: return "gt";
93 case VECC::CC_L: return "lt";
94 case VECC::CC_NE: return "ne";
95 case VECC::CC_EQ: return "eq";
96 case VECC::CC_GE: return "ge";
97 case VECC::CC_LE: return "le";
98 case VECC::CC_NUM: return "num";
99 case VECC::CC_NAN: return "nan";
100 case VECC::CC_GNAN: return "gtnan";
101 case VECC::CC_LNAN: return "ltnan";
102 case VECC::CC_NENAN: return "nenan";
103 case VECC::CC_EQNAN: return "eqnan";
104 case VECC::CC_GENAN: return "genan";
105 case VECC::CC_LENAN: return "lenan";
106 case VECC::CC_AT: return "at";
107 default:
108 llvm_unreachable("Invalid cond code");
109 }
110 }
111
stringToVEICondCode(StringRef S)112 inline static VECC::CondCode stringToVEICondCode(StringRef S) {
113 return StringSwitch<VECC::CondCode>(S)
114 .Case("gt", VECC::CC_IG)
115 .Case("lt", VECC::CC_IL)
116 .Case("ne", VECC::CC_INE)
117 .Case("eq", VECC::CC_IEQ)
118 .Case("ge", VECC::CC_IGE)
119 .Case("le", VECC::CC_ILE)
120 .Case("af", VECC::CC_AF)
121 .Case("at", VECC::CC_AT)
122 .Case("", VECC::CC_AT)
123 .Default(VECC::UNKNOWN);
124 }
125
stringToVEFCondCode(StringRef S)126 inline static VECC::CondCode stringToVEFCondCode(StringRef S) {
127 return StringSwitch<VECC::CondCode>(S)
128 .Case("gt", VECC::CC_G)
129 .Case("lt", VECC::CC_L)
130 .Case("ne", VECC::CC_NE)
131 .Case("eq", VECC::CC_EQ)
132 .Case("ge", VECC::CC_GE)
133 .Case("le", VECC::CC_LE)
134 .Case("num", VECC::CC_NUM)
135 .Case("nan", VECC::CC_NAN)
136 .Case("gtnan", VECC::CC_GNAN)
137 .Case("ltnan", VECC::CC_LNAN)
138 .Case("nenan", VECC::CC_NENAN)
139 .Case("eqnan", VECC::CC_EQNAN)
140 .Case("genan", VECC::CC_GENAN)
141 .Case("lenan", VECC::CC_LENAN)
142 .Case("af", VECC::CC_AF)
143 .Case("at", VECC::CC_AT)
144 .Case("", VECC::CC_AT)
145 .Default(VECC::UNKNOWN);
146 }
147
VECondCodeToVal(VECC::CondCode CC)148 inline static unsigned VECondCodeToVal(VECC::CondCode CC) {
149 switch (CC) {
150 case VECC::CC_IG:
151 return 1;
152 case VECC::CC_IL:
153 return 2;
154 case VECC::CC_INE:
155 return 3;
156 case VECC::CC_IEQ:
157 return 4;
158 case VECC::CC_IGE:
159 return 5;
160 case VECC::CC_ILE:
161 return 6;
162 case VECC::CC_AF:
163 return 0;
164 case VECC::CC_G:
165 return 1;
166 case VECC::CC_L:
167 return 2;
168 case VECC::CC_NE:
169 return 3;
170 case VECC::CC_EQ:
171 return 4;
172 case VECC::CC_GE:
173 return 5;
174 case VECC::CC_LE:
175 return 6;
176 case VECC::CC_NUM:
177 return 7;
178 case VECC::CC_NAN:
179 return 8;
180 case VECC::CC_GNAN:
181 return 9;
182 case VECC::CC_LNAN:
183 return 10;
184 case VECC::CC_NENAN:
185 return 11;
186 case VECC::CC_EQNAN:
187 return 12;
188 case VECC::CC_GENAN:
189 return 13;
190 case VECC::CC_LENAN:
191 return 14;
192 case VECC::CC_AT:
193 return 15;
194 default:
195 llvm_unreachable("Invalid cond code");
196 }
197 }
198
VEValToCondCode(unsigned Val,bool IsInteger)199 inline static VECC::CondCode VEValToCondCode(unsigned Val, bool IsInteger) {
200 if (IsInteger) {
201 switch (Val) {
202 case 0:
203 return VECC::CC_AF;
204 case 1:
205 return VECC::CC_IG;
206 case 2:
207 return VECC::CC_IL;
208 case 3:
209 return VECC::CC_INE;
210 case 4:
211 return VECC::CC_IEQ;
212 case 5:
213 return VECC::CC_IGE;
214 case 6:
215 return VECC::CC_ILE;
216 case 15:
217 return VECC::CC_AT;
218 }
219 } else {
220 switch (Val) {
221 case 0:
222 return VECC::CC_AF;
223 case 1:
224 return VECC::CC_G;
225 case 2:
226 return VECC::CC_L;
227 case 3:
228 return VECC::CC_NE;
229 case 4:
230 return VECC::CC_EQ;
231 case 5:
232 return VECC::CC_GE;
233 case 6:
234 return VECC::CC_LE;
235 case 7:
236 return VECC::CC_NUM;
237 case 8:
238 return VECC::CC_NAN;
239 case 9:
240 return VECC::CC_GNAN;
241 case 10:
242 return VECC::CC_LNAN;
243 case 11:
244 return VECC::CC_NENAN;
245 case 12:
246 return VECC::CC_EQNAN;
247 case 13:
248 return VECC::CC_GENAN;
249 case 14:
250 return VECC::CC_LENAN;
251 case 15:
252 return VECC::CC_AT;
253 }
254 }
255 llvm_unreachable("Invalid cond code");
256 }
257
VERDToString(VERD::RoundingMode R)258 inline static const char *VERDToString(VERD::RoundingMode R) {
259 switch (R) {
260 case VERD::RD_NONE:
261 return "";
262 case VERD::RD_RZ:
263 return ".rz";
264 case VERD::RD_RP:
265 return ".rp";
266 case VERD::RD_RM:
267 return ".rm";
268 case VERD::RD_RN:
269 return ".rn";
270 case VERD::RD_RA:
271 return ".ra";
272 default:
273 llvm_unreachable("Invalid branch predicate");
274 }
275 }
276
stringToVERD(StringRef S)277 inline static VERD::RoundingMode stringToVERD(StringRef S) {
278 return StringSwitch<VERD::RoundingMode>(S)
279 .Case("", VERD::RD_NONE)
280 .Case(".rz", VERD::RD_RZ)
281 .Case(".rp", VERD::RD_RP)
282 .Case(".rm", VERD::RD_RM)
283 .Case(".rn", VERD::RD_RN)
284 .Case(".ra", VERD::RD_RA)
285 .Default(VERD::UNKNOWN);
286 }
287
VERDToVal(VERD::RoundingMode R)288 inline static unsigned VERDToVal(VERD::RoundingMode R) {
289 switch (R) {
290 case VERD::RD_NONE:
291 case VERD::RD_RZ:
292 case VERD::RD_RP:
293 case VERD::RD_RM:
294 case VERD::RD_RN:
295 case VERD::RD_RA:
296 return static_cast<unsigned>(R);
297 default:
298 break;
299 }
300 llvm_unreachable("Invalid branch predicates");
301 }
302
VEValToRD(unsigned Val)303 inline static VERD::RoundingMode VEValToRD(unsigned Val) {
304 switch (Val) {
305 case static_cast<unsigned>(VERD::RD_NONE):
306 return VERD::RD_NONE;
307 case static_cast<unsigned>(VERD::RD_RZ):
308 return VERD::RD_RZ;
309 case static_cast<unsigned>(VERD::RD_RP):
310 return VERD::RD_RP;
311 case static_cast<unsigned>(VERD::RD_RM):
312 return VERD::RD_RM;
313 case static_cast<unsigned>(VERD::RD_RN):
314 return VERD::RD_RN;
315 case static_cast<unsigned>(VERD::RD_RA):
316 return VERD::RD_RA;
317 default:
318 break;
319 }
320 llvm_unreachable("Invalid branch predicates");
321 }
322
323 // MImm - Special immediate value of sequential bit stream of 0 or 1.
324 // See VEInstrInfo.td for details.
isMImmVal(uint64_t Val)325 inline static bool isMImmVal(uint64_t Val) {
326 if (Val == 0) {
327 // (0)1 is 0
328 return true;
329 }
330 if (isMask_64(Val)) {
331 // (m)0 patterns
332 return true;
333 }
334 // (m)1 patterns
335 return (Val & (UINT64_C(1) << 63)) && isShiftedMask_64(Val);
336 }
337
isMImm32Val(uint32_t Val)338 inline static bool isMImm32Val(uint32_t Val) {
339 if (Val == 0) {
340 // (0)1 is 0
341 return true;
342 }
343 if (isMask_32(Val)) {
344 // (m)0 patterns
345 return true;
346 }
347 // (m)1 patterns
348 return (Val & (UINT32_C(1) << 31)) && isShiftedMask_32(Val);
349 }
350
351 /// val2MImm - Convert an integer immediate value to target MImm immediate.
val2MImm(uint64_t Val)352 inline static uint64_t val2MImm(uint64_t Val) {
353 if (Val == 0)
354 return 0; // (0)1
355 if (Val & (UINT64_C(1) << 63))
356 return countLeadingOnes(Val); // (m)1
357 return countLeadingZeros(Val) | 0x40; // (m)0
358 }
359
360 /// mimm2Val - Convert a target MImm immediate to an integer immediate value.
mimm2Val(uint64_t Val)361 inline static uint64_t mimm2Val(uint64_t Val) {
362 if (Val == 0)
363 return 0; // (0)1
364 if ((Val & 0x40) == 0)
365 return (uint64_t)((INT64_C(1) << 63) >> (Val & 0x3f)); // (m)1
366 return ((uint64_t)INT64_C(-1) >> (Val & 0x3f)); // (m)0
367 }
368
M0(unsigned Val)369 inline unsigned M0(unsigned Val) { return Val + 64; }
M1(unsigned Val)370 inline unsigned M1(unsigned Val) { return Val; }
371
372 static const unsigned StandardVectorWidth = 256;
373 static const unsigned PackedVectorWidth = 512;
374
375 } // namespace llvm
376 #endif
377