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