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