xref: /freebsd/contrib/llvm-project/llvm/lib/Target/VE/VE.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 AsmPrinter;
24 class FunctionPass;
25 class MCInst;
26 class MachineInstr;
27 class PassRegistry;
28 class VETargetMachine;
29 
30 FunctionPass *createVEISelDag(VETargetMachine &TM);
31 FunctionPass *createLVLGenPass();
32 void initializeVEAsmPrinterPass(PassRegistry &);
33 void initializeVEDAGToDAGISelLegacyPass(PassRegistry &);
34 
35 void LowerVEMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
36                                  AsmPrinter &AP);
37 } // namespace llvm
38 
39 namespace 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.
42 namespace VECC {
43 enum 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.
74 namespace VERD {
75 enum 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 
VECondCodeToString(VECC::CondCode CC)86 inline 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 
stringToVEICondCode(StringRef S)115 inline static VECC::CondCode stringToVEICondCode(StringRef S) {
116   return StringSwitch<VECC::CondCode>(S)
117       .Case("gt", VECC::CC_IG)
118       .Case("lt", VECC::CC_IL)
119       .Case("ne", VECC::CC_INE)
120       .Case("eq", VECC::CC_IEQ)
121       .Case("ge", VECC::CC_IGE)
122       .Case("le", VECC::CC_ILE)
123       .Case("af", VECC::CC_AF)
124       .Case("at", VECC::CC_AT)
125       .Case("", VECC::CC_AT)
126       .Default(VECC::UNKNOWN);
127 }
128 
stringToVEFCondCode(StringRef S)129 inline static VECC::CondCode stringToVEFCondCode(StringRef S) {
130   return StringSwitch<VECC::CondCode>(S)
131       .Case("gt", VECC::CC_G)
132       .Case("lt", VECC::CC_L)
133       .Case("ne", VECC::CC_NE)
134       .Case("eq", VECC::CC_EQ)
135       .Case("ge", VECC::CC_GE)
136       .Case("le", VECC::CC_LE)
137       .Case("num", VECC::CC_NUM)
138       .Case("nan", VECC::CC_NAN)
139       .Case("gtnan", VECC::CC_GNAN)
140       .Case("ltnan", VECC::CC_LNAN)
141       .Case("nenan", VECC::CC_NENAN)
142       .Case("eqnan", VECC::CC_EQNAN)
143       .Case("genan", VECC::CC_GENAN)
144       .Case("lenan", VECC::CC_LENAN)
145       .Case("af", VECC::CC_AF)
146       .Case("at", VECC::CC_AT)
147       .Case("", VECC::CC_AT)
148       .Default(VECC::UNKNOWN);
149 }
150 
isIntVECondCode(VECC::CondCode CC)151 inline static bool isIntVECondCode(VECC::CondCode CC) {
152   return CC < VECC::CC_AF;
153 }
154 
VECondCodeToVal(VECC::CondCode CC)155 inline 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 
VEValToCondCode(unsigned Val,bool IsInteger)206 inline 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 
VERDToString(VERD::RoundingMode R)265 inline 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 
stringToVERD(StringRef S)284 inline static VERD::RoundingMode stringToVERD(StringRef S) {
285   return StringSwitch<VERD::RoundingMode>(S)
286       .Case("", VERD::RD_NONE)
287       .Case(".rz", VERD::RD_RZ)
288       .Case(".rp", VERD::RD_RP)
289       .Case(".rm", VERD::RD_RM)
290       .Case(".rn", VERD::RD_RN)
291       .Case(".ra", VERD::RD_RA)
292       .Default(VERD::UNKNOWN);
293 }
294 
VERDToVal(VERD::RoundingMode R)295 inline 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 
VEValToRD(unsigned Val)310 inline 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.
isMImmVal(uint64_t Val)332 inline static bool isMImmVal(uint64_t Val) {
333   if (Val == 0) {
334     // (0)1 is 0
335     return true;
336   }
337   if (isMask_64(Val)) {
338     // (m)0 patterns
339     return true;
340   }
341   // (m)1 patterns
342   return (Val & (UINT64_C(1) << 63)) && isShiftedMask_64(Val);
343 }
344 
isMImm32Val(uint32_t Val)345 inline static bool isMImm32Val(uint32_t Val) {
346   if (Val == 0) {
347     // (0)1 is 0
348     return true;
349   }
350   if (isMask_32(Val)) {
351     // (m)0 patterns
352     return true;
353   }
354   // (m)1 patterns
355   return (Val & (UINT32_C(1) << 31)) && isShiftedMask_32(Val);
356 }
357 
358 /// val2MImm - Convert an integer immediate value to target MImm immediate.
val2MImm(uint64_t Val)359 inline 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(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.
mimm2Val(uint64_t Val)368 inline 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 
M0(unsigned Val)376 inline unsigned M0(unsigned Val) { return Val + 64; }
M1(unsigned Val)377 inline unsigned M1(unsigned Val) { return Val; }
378 
379 static const unsigned StandardVectorWidth = 256;
380 static const unsigned PackedVectorWidth = 512;
381 
382 } // namespace llvm
383 #endif
384