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 llvm::countl_one(Val); // (m)1 455 return llvm::countl_zero(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