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 formatted_raw_ostream; 26 class AsmPrinter; 27 class MCInst; 28 class MachineInstr; 29 30 FunctionPass *createVEISelDag(VETargetMachine &TM); 31 FunctionPass *createVEPromoteToI1Pass(); 32 FunctionPass *createLVLGenPass(); 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 unsigned VECondCodeToVal(VECC::CondCode CC) { 151 switch (CC) { 152 case VECC::CC_IG: 153 return 1; 154 case VECC::CC_IL: 155 return 2; 156 case VECC::CC_INE: 157 return 3; 158 case VECC::CC_IEQ: 159 return 4; 160 case VECC::CC_IGE: 161 return 5; 162 case VECC::CC_ILE: 163 return 6; 164 case VECC::CC_AF: 165 return 0; 166 case VECC::CC_G: 167 return 1; 168 case VECC::CC_L: 169 return 2; 170 case VECC::CC_NE: 171 return 3; 172 case VECC::CC_EQ: 173 return 4; 174 case VECC::CC_GE: 175 return 5; 176 case VECC::CC_LE: 177 return 6; 178 case VECC::CC_NUM: 179 return 7; 180 case VECC::CC_NAN: 181 return 8; 182 case VECC::CC_GNAN: 183 return 9; 184 case VECC::CC_LNAN: 185 return 10; 186 case VECC::CC_NENAN: 187 return 11; 188 case VECC::CC_EQNAN: 189 return 12; 190 case VECC::CC_GENAN: 191 return 13; 192 case VECC::CC_LENAN: 193 return 14; 194 case VECC::CC_AT: 195 return 15; 196 default: 197 llvm_unreachable("Invalid cond code"); 198 } 199 } 200 201 inline static VECC::CondCode VEValToCondCode(unsigned Val, bool IsInteger) { 202 if (IsInteger) { 203 switch (Val) { 204 case 0: 205 return VECC::CC_AF; 206 case 1: 207 return VECC::CC_IG; 208 case 2: 209 return VECC::CC_IL; 210 case 3: 211 return VECC::CC_INE; 212 case 4: 213 return VECC::CC_IEQ; 214 case 5: 215 return VECC::CC_IGE; 216 case 6: 217 return VECC::CC_ILE; 218 case 15: 219 return VECC::CC_AT; 220 } 221 } else { 222 switch (Val) { 223 case 0: 224 return VECC::CC_AF; 225 case 1: 226 return VECC::CC_G; 227 case 2: 228 return VECC::CC_L; 229 case 3: 230 return VECC::CC_NE; 231 case 4: 232 return VECC::CC_EQ; 233 case 5: 234 return VECC::CC_GE; 235 case 6: 236 return VECC::CC_LE; 237 case 7: 238 return VECC::CC_NUM; 239 case 8: 240 return VECC::CC_NAN; 241 case 9: 242 return VECC::CC_GNAN; 243 case 10: 244 return VECC::CC_LNAN; 245 case 11: 246 return VECC::CC_NENAN; 247 case 12: 248 return VECC::CC_EQNAN; 249 case 13: 250 return VECC::CC_GENAN; 251 case 14: 252 return VECC::CC_LENAN; 253 case 15: 254 return VECC::CC_AT; 255 } 256 } 257 llvm_unreachable("Invalid cond code"); 258 } 259 260 inline static const char *VERDToString(VERD::RoundingMode R) { 261 switch (R) { 262 case VERD::RD_NONE: 263 return ""; 264 case VERD::RD_RZ: 265 return ".rz"; 266 case VERD::RD_RP: 267 return ".rp"; 268 case VERD::RD_RM: 269 return ".rm"; 270 case VERD::RD_RN: 271 return ".rn"; 272 case VERD::RD_RA: 273 return ".ra"; 274 default: 275 llvm_unreachable("Invalid branch predicate"); 276 } 277 } 278 279 inline static VERD::RoundingMode stringToVERD(StringRef S) { 280 return StringSwitch<VERD::RoundingMode>(S) 281 .Case("", VERD::RD_NONE) 282 .Case(".rz", VERD::RD_RZ) 283 .Case(".rp", VERD::RD_RP) 284 .Case(".rm", VERD::RD_RM) 285 .Case(".rn", VERD::RD_RN) 286 .Case(".ra", VERD::RD_RA) 287 .Default(VERD::UNKNOWN); 288 } 289 290 inline static unsigned VERDToVal(VERD::RoundingMode R) { 291 switch (R) { 292 case VERD::RD_NONE: 293 case VERD::RD_RZ: 294 case VERD::RD_RP: 295 case VERD::RD_RM: 296 case VERD::RD_RN: 297 case VERD::RD_RA: 298 return static_cast<unsigned>(R); 299 default: 300 break; 301 } 302 llvm_unreachable("Invalid branch predicates"); 303 } 304 305 inline static VERD::RoundingMode VEValToRD(unsigned Val) { 306 switch (Val) { 307 case static_cast<unsigned>(VERD::RD_NONE): 308 return VERD::RD_NONE; 309 case static_cast<unsigned>(VERD::RD_RZ): 310 return VERD::RD_RZ; 311 case static_cast<unsigned>(VERD::RD_RP): 312 return VERD::RD_RP; 313 case static_cast<unsigned>(VERD::RD_RM): 314 return VERD::RD_RM; 315 case static_cast<unsigned>(VERD::RD_RN): 316 return VERD::RD_RN; 317 case static_cast<unsigned>(VERD::RD_RA): 318 return VERD::RD_RA; 319 default: 320 break; 321 } 322 llvm_unreachable("Invalid branch predicates"); 323 } 324 325 // MImm - Special immediate value of sequential bit stream of 0 or 1. 326 // See VEInstrInfo.td for details. 327 inline static bool isMImmVal(uint64_t Val) { 328 if (Val == 0) { 329 // (0)1 is 0 330 return true; 331 } 332 if (isMask_64(Val)) { 333 // (m)0 patterns 334 return true; 335 } 336 // (m)1 patterns 337 return (Val & (UINT64_C(1) << 63)) && isShiftedMask_64(Val); 338 } 339 340 inline static bool isMImm32Val(uint32_t Val) { 341 if (Val == 0) { 342 // (0)1 is 0 343 return true; 344 } 345 if (isMask_32(Val)) { 346 // (m)0 patterns 347 return true; 348 } 349 // (m)1 patterns 350 return (Val & (UINT32_C(1) << 31)) && isShiftedMask_32(Val); 351 } 352 353 /// val2MImm - Convert an integer immediate value to target MImm immediate. 354 inline static uint64_t val2MImm(uint64_t Val) { 355 if (Val == 0) 356 return 0; // (0)1 357 if (Val & (UINT64_C(1) << 63)) 358 return countLeadingOnes(Val); // (m)1 359 return countLeadingZeros(Val) | 0x40; // (m)0 360 } 361 362 /// mimm2Val - Convert a target MImm immediate to an integer immediate value. 363 inline static uint64_t mimm2Val(uint64_t Val) { 364 if (Val == 0) 365 return 0; // (0)1 366 if ((Val & 0x40) == 0) 367 return (uint64_t)((INT64_C(1) << 63) >> (Val & 0x3f)); // (m)1 368 return ((uint64_t)INT64_C(-1) >> (Val & 0x3f)); // (m)0 369 } 370 371 inline unsigned M0(unsigned Val) { return Val + 64; } 372 inline unsigned M1(unsigned Val) { return Val; } 373 374 } // namespace llvm 375 #endif 376