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 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 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 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 150 inline static bool isIntVECondCode(VECC::CondCode CC) { 151 return CC < VECC::CC_AF; 152 } 153 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 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 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 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 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 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. 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 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. 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. 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 375 inline unsigned M0(unsigned Val) { return Val + 64; } 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