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