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