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/CodeGen/ISDOpcodes.h"
20 #include "llvm/CodeGen/SelectionDAGNodes.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Target/TargetMachine.h"
23 
24 namespace llvm {
25 class AsmPrinter;
26 class FunctionPass;
27 class MCInst;
28 class MachineInstr;
29 class PassRegistry;
30 class VETargetMachine;
31 
32 FunctionPass *createVEISelDag(VETargetMachine &TM);
33 FunctionPass *createLVLGenPass();
34 void initializeVEDAGToDAGISelPass(PassRegistry &);
35 
36 void LowerVEMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
37                                  AsmPrinter &AP);
38 } // namespace llvm
39 
40 namespace llvm {
41 // Enums corresponding to VE condition codes, both icc's and fcc's.  These
42 // values must be kept in sync with the ones in the .td file.
43 namespace VECC {
44 enum CondCode {
45   // Integer comparison
46   CC_IG = 0,  // Greater
47   CC_IL = 1,  // Less
48   CC_INE = 2, // Not Equal
49   CC_IEQ = 3, // Equal
50   CC_IGE = 4, // Greater or Equal
51   CC_ILE = 5, // Less or Equal
52 
53   // Floating point comparison
54   CC_AF = 0 + 6,     // Never
55   CC_G = 1 + 6,      // Greater
56   CC_L = 2 + 6,      // Less
57   CC_NE = 3 + 6,     // Not Equal
58   CC_EQ = 4 + 6,     // Equal
59   CC_GE = 5 + 6,     // Greater or Equal
60   CC_LE = 6 + 6,     // Less or Equal
61   CC_NUM = 7 + 6,    // Number
62   CC_NAN = 8 + 6,    // NaN
63   CC_GNAN = 9 + 6,   // Greater or NaN
64   CC_LNAN = 10 + 6,  // Less or NaN
65   CC_NENAN = 11 + 6, // Not Equal or NaN
66   CC_EQNAN = 12 + 6, // Equal or NaN
67   CC_GENAN = 13 + 6, // Greater or Equal or NaN
68   CC_LENAN = 14 + 6, // Less or Equal or NaN
69   CC_AT = 15 + 6,    // Always
70   UNKNOWN
71 };
72 }
73 // Enums corresponding to VE Rounding Mode.  These values must be kept in
74 // sync with the ones in the .td file.
75 namespace VERD {
76 enum RoundingMode {
77   RD_NONE = 0, // According to PSW
78   RD_RZ = 8,   // Round toward Zero
79   RD_RP = 9,   // Round toward Plus infinity
80   RD_RM = 10,  // Round toward Minus infinity
81   RD_RN = 11,  // Round to Nearest (ties to Even)
82   RD_RA = 12,  // Round to Nearest (ties to Away)
83   UNKNOWN
84 };
85 }
86 
87 inline static const char *VECondCodeToString(VECC::CondCode CC) {
88   switch (CC) {
89   case VECC::CC_IG:    return "gt";
90   case VECC::CC_IL:    return "lt";
91   case VECC::CC_INE:   return "ne";
92   case VECC::CC_IEQ:   return "eq";
93   case VECC::CC_IGE:   return "ge";
94   case VECC::CC_ILE:   return "le";
95   case VECC::CC_AF:    return "af";
96   case VECC::CC_G:     return "gt";
97   case VECC::CC_L:     return "lt";
98   case VECC::CC_NE:    return "ne";
99   case VECC::CC_EQ:    return "eq";
100   case VECC::CC_GE:    return "ge";
101   case VECC::CC_LE:    return "le";
102   case VECC::CC_NUM:   return "num";
103   case VECC::CC_NAN:   return "nan";
104   case VECC::CC_GNAN:  return "gtnan";
105   case VECC::CC_LNAN:  return "ltnan";
106   case VECC::CC_NENAN: return "nenan";
107   case VECC::CC_EQNAN: return "eqnan";
108   case VECC::CC_GENAN: return "genan";
109   case VECC::CC_LENAN: return "lenan";
110   case VECC::CC_AT:    return "at";
111   default:
112     llvm_unreachable("Invalid cond code");
113   }
114 }
115 
116 inline static VECC::CondCode stringToVEICondCode(StringRef S) {
117   return StringSwitch<VECC::CondCode>(S)
118       .Case("gt", VECC::CC_IG)
119       .Case("lt", VECC::CC_IL)
120       .Case("ne", VECC::CC_INE)
121       .Case("eq", VECC::CC_IEQ)
122       .Case("ge", VECC::CC_IGE)
123       .Case("le", VECC::CC_ILE)
124       .Case("af", VECC::CC_AF)
125       .Case("at", VECC::CC_AT)
126       .Case("", VECC::CC_AT)
127       .Default(VECC::UNKNOWN);
128 }
129 
130 inline static VECC::CondCode stringToVEFCondCode(StringRef S) {
131   return StringSwitch<VECC::CondCode>(S)
132       .Case("gt", VECC::CC_G)
133       .Case("lt", VECC::CC_L)
134       .Case("ne", VECC::CC_NE)
135       .Case("eq", VECC::CC_EQ)
136       .Case("ge", VECC::CC_GE)
137       .Case("le", VECC::CC_LE)
138       .Case("num", VECC::CC_NUM)
139       .Case("nan", VECC::CC_NAN)
140       .Case("gtnan", VECC::CC_GNAN)
141       .Case("ltnan", VECC::CC_LNAN)
142       .Case("nenan", VECC::CC_NENAN)
143       .Case("eqnan", VECC::CC_EQNAN)
144       .Case("genan", VECC::CC_GENAN)
145       .Case("lenan", VECC::CC_LENAN)
146       .Case("af", VECC::CC_AF)
147       .Case("at", VECC::CC_AT)
148       .Case("", VECC::CC_AT)
149       .Default(VECC::UNKNOWN);
150 }
151 
152 inline static bool isIntVECondCode(VECC::CondCode CC) {
153   return CC < VECC::CC_AF;
154 }
155 
156 inline static unsigned VECondCodeToVal(VECC::CondCode CC) {
157   switch (CC) {
158   case VECC::CC_IG:
159     return 1;
160   case VECC::CC_IL:
161     return 2;
162   case VECC::CC_INE:
163     return 3;
164   case VECC::CC_IEQ:
165     return 4;
166   case VECC::CC_IGE:
167     return 5;
168   case VECC::CC_ILE:
169     return 6;
170   case VECC::CC_AF:
171     return 0;
172   case VECC::CC_G:
173     return 1;
174   case VECC::CC_L:
175     return 2;
176   case VECC::CC_NE:
177     return 3;
178   case VECC::CC_EQ:
179     return 4;
180   case VECC::CC_GE:
181     return 5;
182   case VECC::CC_LE:
183     return 6;
184   case VECC::CC_NUM:
185     return 7;
186   case VECC::CC_NAN:
187     return 8;
188   case VECC::CC_GNAN:
189     return 9;
190   case VECC::CC_LNAN:
191     return 10;
192   case VECC::CC_NENAN:
193     return 11;
194   case VECC::CC_EQNAN:
195     return 12;
196   case VECC::CC_GENAN:
197     return 13;
198   case VECC::CC_LENAN:
199     return 14;
200   case VECC::CC_AT:
201     return 15;
202   default:
203     llvm_unreachable("Invalid cond code");
204   }
205 }
206 
207 /// Convert a DAG integer condition code to a VE ICC condition.
208 inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) {
209   switch (CC) {
210   default:
211     llvm_unreachable("Unknown integer condition code!");
212   case ISD::SETEQ:
213     return VECC::CC_IEQ;
214   case ISD::SETNE:
215     return VECC::CC_INE;
216   case ISD::SETLT:
217     return VECC::CC_IL;
218   case ISD::SETGT:
219     return VECC::CC_IG;
220   case ISD::SETLE:
221     return VECC::CC_ILE;
222   case ISD::SETGE:
223     return VECC::CC_IGE;
224   case ISD::SETULT:
225     return VECC::CC_IL;
226   case ISD::SETULE:
227     return VECC::CC_ILE;
228   case ISD::SETUGT:
229     return VECC::CC_IG;
230   case ISD::SETUGE:
231     return VECC::CC_IGE;
232   }
233 }
234 
235 /// Convert a DAG floating point condition code to a VE FCC condition.
236 inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) {
237   switch (CC) {
238   default:
239     llvm_unreachable("Unknown fp condition code!");
240   case ISD::SETFALSE:
241     return VECC::CC_AF;
242   case ISD::SETEQ:
243   case ISD::SETOEQ:
244     return VECC::CC_EQ;
245   case ISD::SETNE:
246   case ISD::SETONE:
247     return VECC::CC_NE;
248   case ISD::SETLT:
249   case ISD::SETOLT:
250     return VECC::CC_L;
251   case ISD::SETGT:
252   case ISD::SETOGT:
253     return VECC::CC_G;
254   case ISD::SETLE:
255   case ISD::SETOLE:
256     return VECC::CC_LE;
257   case ISD::SETGE:
258   case ISD::SETOGE:
259     return VECC::CC_GE;
260   case ISD::SETO:
261     return VECC::CC_NUM;
262   case ISD::SETUO:
263     return VECC::CC_NAN;
264   case ISD::SETUEQ:
265     return VECC::CC_EQNAN;
266   case ISD::SETUNE:
267     return VECC::CC_NENAN;
268   case ISD::SETULT:
269     return VECC::CC_LNAN;
270   case ISD::SETUGT:
271     return VECC::CC_GNAN;
272   case ISD::SETULE:
273     return VECC::CC_LENAN;
274   case ISD::SETUGE:
275     return VECC::CC_GENAN;
276   case ISD::SETTRUE:
277     return VECC::CC_AT;
278   }
279 }
280 
281 inline static VECC::CondCode VEValToCondCode(unsigned Val, bool IsInteger) {
282   if (IsInteger) {
283     switch (Val) {
284     case 0:
285       return VECC::CC_AF;
286     case 1:
287       return VECC::CC_IG;
288     case 2:
289       return VECC::CC_IL;
290     case 3:
291       return VECC::CC_INE;
292     case 4:
293       return VECC::CC_IEQ;
294     case 5:
295       return VECC::CC_IGE;
296     case 6:
297       return VECC::CC_ILE;
298     case 15:
299       return VECC::CC_AT;
300     }
301   } else {
302     switch (Val) {
303     case 0:
304       return VECC::CC_AF;
305     case 1:
306       return VECC::CC_G;
307     case 2:
308       return VECC::CC_L;
309     case 3:
310       return VECC::CC_NE;
311     case 4:
312       return VECC::CC_EQ;
313     case 5:
314       return VECC::CC_GE;
315     case 6:
316       return VECC::CC_LE;
317     case 7:
318       return VECC::CC_NUM;
319     case 8:
320       return VECC::CC_NAN;
321     case 9:
322       return VECC::CC_GNAN;
323     case 10:
324       return VECC::CC_LNAN;
325     case 11:
326       return VECC::CC_NENAN;
327     case 12:
328       return VECC::CC_EQNAN;
329     case 13:
330       return VECC::CC_GENAN;
331     case 14:
332       return VECC::CC_LENAN;
333     case 15:
334       return VECC::CC_AT;
335     }
336   }
337   llvm_unreachable("Invalid cond code");
338 }
339 
340 inline static const char *VERDToString(VERD::RoundingMode R) {
341   switch (R) {
342   case VERD::RD_NONE:
343     return "";
344   case VERD::RD_RZ:
345     return ".rz";
346   case VERD::RD_RP:
347     return ".rp";
348   case VERD::RD_RM:
349     return ".rm";
350   case VERD::RD_RN:
351     return ".rn";
352   case VERD::RD_RA:
353     return ".ra";
354   default:
355     llvm_unreachable("Invalid branch predicate");
356   }
357 }
358 
359 inline static VERD::RoundingMode stringToVERD(StringRef S) {
360   return StringSwitch<VERD::RoundingMode>(S)
361       .Case("", VERD::RD_NONE)
362       .Case(".rz", VERD::RD_RZ)
363       .Case(".rp", VERD::RD_RP)
364       .Case(".rm", VERD::RD_RM)
365       .Case(".rn", VERD::RD_RN)
366       .Case(".ra", VERD::RD_RA)
367       .Default(VERD::UNKNOWN);
368 }
369 
370 inline static unsigned VERDToVal(VERD::RoundingMode R) {
371   switch (R) {
372   case VERD::RD_NONE:
373   case VERD::RD_RZ:
374   case VERD::RD_RP:
375   case VERD::RD_RM:
376   case VERD::RD_RN:
377   case VERD::RD_RA:
378     return static_cast<unsigned>(R);
379   default:
380     break;
381   }
382   llvm_unreachable("Invalid branch predicates");
383 }
384 
385 inline static VERD::RoundingMode VEValToRD(unsigned Val) {
386   switch (Val) {
387   case static_cast<unsigned>(VERD::RD_NONE):
388     return VERD::RD_NONE;
389   case static_cast<unsigned>(VERD::RD_RZ):
390     return VERD::RD_RZ;
391   case static_cast<unsigned>(VERD::RD_RP):
392     return VERD::RD_RP;
393   case static_cast<unsigned>(VERD::RD_RM):
394     return VERD::RD_RM;
395   case static_cast<unsigned>(VERD::RD_RN):
396     return VERD::RD_RN;
397   case static_cast<unsigned>(VERD::RD_RA):
398     return VERD::RD_RA;
399   default:
400     break;
401   }
402   llvm_unreachable("Invalid branch predicates");
403 }
404 
405 /// getImmVal - get immediate representation of integer value
406 inline static uint64_t getImmVal(const ConstantSDNode *N) {
407   return N->getSExtValue();
408 }
409 
410 /// getFpImmVal - get immediate representation of floating point value
411 inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) {
412   const APInt &Imm = N->getValueAPF().bitcastToAPInt();
413   uint64_t Val = Imm.getZExtValue();
414   if (Imm.getBitWidth() == 32) {
415     // Immediate value of float place places at higher bits on VE.
416     Val <<= 32;
417   }
418   return Val;
419 }
420 
421 // MImm - Special immediate value of sequential bit stream of 0 or 1.
422 //   See VEInstrInfo.td for details.
423 inline static bool isMImmVal(uint64_t Val) {
424   if (Val == 0) {
425     // (0)1 is 0
426     return true;
427   }
428   if (isMask_64(Val)) {
429     // (m)0 patterns
430     return true;
431   }
432   // (m)1 patterns
433   return (Val & (UINT64_C(1) << 63)) && isShiftedMask_64(Val);
434 }
435 
436 inline static bool isMImm32Val(uint32_t Val) {
437   if (Val == 0) {
438     // (0)1 is 0
439     return true;
440   }
441   if (isMask_32(Val)) {
442     // (m)0 patterns
443     return true;
444   }
445   // (m)1 patterns
446   return (Val & (UINT32_C(1) << 31)) && isShiftedMask_32(Val);
447 }
448 
449 /// val2MImm - Convert an integer immediate value to target MImm immediate.
450 inline static uint64_t val2MImm(uint64_t Val) {
451   if (Val == 0)
452     return 0; // (0)1
453   if (Val & (UINT64_C(1) << 63))
454     return countLeadingOnes(Val);       // (m)1
455   return countLeadingZeros(Val) | 0x40; // (m)0
456 }
457 
458 /// mimm2Val - Convert a target MImm immediate to an integer immediate value.
459 inline static uint64_t mimm2Val(uint64_t Val) {
460   if (Val == 0)
461     return 0; // (0)1
462   if ((Val & 0x40) == 0)
463     return (uint64_t)((INT64_C(1) << 63) >> (Val & 0x3f)); // (m)1
464   return ((uint64_t)INT64_C(-1) >> (Val & 0x3f));          // (m)0
465 }
466 
467 inline unsigned M0(unsigned Val) { return Val + 64; }
468 inline unsigned M1(unsigned Val) { return Val; }
469 
470 static const unsigned StandardVectorWidth = 256;
471 static const unsigned PackedVectorWidth = 512;
472 
473 } // namespace llvm
474 #endif
475