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