1480093f4SDimitry Andric //===-- VE.h - Top-level interface for VE representation --------*- C++ -*-===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric // 9480093f4SDimitry Andric // This file contains the entry points for global functions defined in the LLVM 10480093f4SDimitry Andric // VE back-end. 11480093f4SDimitry Andric // 12480093f4SDimitry Andric //===----------------------------------------------------------------------===// 13480093f4SDimitry Andric 14480093f4SDimitry Andric #ifndef LLVM_LIB_TARGET_VE_VE_H 15480093f4SDimitry Andric #define LLVM_LIB_TARGET_VE_VE_H 16480093f4SDimitry Andric 17480093f4SDimitry Andric #include "MCTargetDesc/VEMCTargetDesc.h" 18*5ffd83dbSDimitry Andric #include "llvm/ADT/StringSwitch.h" 19480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h" 20480093f4SDimitry Andric #include "llvm/Target/TargetMachine.h" 21480093f4SDimitry Andric 22480093f4SDimitry Andric namespace llvm { 23480093f4SDimitry Andric class FunctionPass; 24480093f4SDimitry Andric class VETargetMachine; 25480093f4SDimitry Andric class formatted_raw_ostream; 26480093f4SDimitry Andric class AsmPrinter; 27480093f4SDimitry Andric class MCInst; 28480093f4SDimitry Andric class MachineInstr; 29480093f4SDimitry Andric 30480093f4SDimitry Andric FunctionPass *createVEISelDag(VETargetMachine &TM); 31480093f4SDimitry Andric FunctionPass *createVEPromoteToI1Pass(); 32480093f4SDimitry Andric 33480093f4SDimitry Andric void LowerVEMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 34480093f4SDimitry Andric AsmPrinter &AP); 35480093f4SDimitry Andric } // namespace llvm 36480093f4SDimitry Andric 37480093f4SDimitry Andric namespace llvm { 38480093f4SDimitry Andric // Enums corresponding to VE condition codes, both icc's and fcc's. These 39480093f4SDimitry Andric // values must be kept in sync with the ones in the .td file. 40480093f4SDimitry Andric namespace VECC { 41*5ffd83dbSDimitry Andric enum CondCode { 42480093f4SDimitry Andric // Integer comparison 43480093f4SDimitry Andric CC_IG = 0, // Greater 44480093f4SDimitry Andric CC_IL = 1, // Less 45480093f4SDimitry Andric CC_INE = 2, // Not Equal 46480093f4SDimitry Andric CC_IEQ = 3, // Equal 47480093f4SDimitry Andric CC_IGE = 4, // Greater or Equal 48480093f4SDimitry Andric CC_ILE = 5, // Less or Equal 49480093f4SDimitry Andric 50480093f4SDimitry Andric // Floating point comparison 51480093f4SDimitry Andric CC_AF = 0 + 6, // Never 52480093f4SDimitry Andric CC_G = 1 + 6, // Greater 53480093f4SDimitry Andric CC_L = 2 + 6, // Less 54480093f4SDimitry Andric CC_NE = 3 + 6, // Not Equal 55480093f4SDimitry Andric CC_EQ = 4 + 6, // Equal 56480093f4SDimitry Andric CC_GE = 5 + 6, // Greater or Equal 57480093f4SDimitry Andric CC_LE = 6 + 6, // Less or Equal 58480093f4SDimitry Andric CC_NUM = 7 + 6, // Number 59480093f4SDimitry Andric CC_NAN = 8 + 6, // NaN 60480093f4SDimitry Andric CC_GNAN = 9 + 6, // Greater or NaN 61480093f4SDimitry Andric CC_LNAN = 10 + 6, // Less or NaN 62480093f4SDimitry Andric CC_NENAN = 11 + 6, // Not Equal or NaN 63480093f4SDimitry Andric CC_EQNAN = 12 + 6, // Equal or NaN 64480093f4SDimitry Andric CC_GENAN = 13 + 6, // Greater or Equal or NaN 65480093f4SDimitry Andric CC_LENAN = 14 + 6, // Less or Equal or NaN 66480093f4SDimitry Andric CC_AT = 15 + 6, // Always 67*5ffd83dbSDimitry Andric UNKNOWN 68*5ffd83dbSDimitry Andric }; 69*5ffd83dbSDimitry Andric } 70*5ffd83dbSDimitry Andric // Enums corresponding to VE Rounding Mode. These values must be kept in 71*5ffd83dbSDimitry Andric // sync with the ones in the .td file. 72*5ffd83dbSDimitry Andric namespace VERD { 73*5ffd83dbSDimitry Andric enum RoundingMode { 74*5ffd83dbSDimitry Andric RD_NONE = 0, // According to PSW 75*5ffd83dbSDimitry Andric RD_RZ = 8, // Round toward Zero 76*5ffd83dbSDimitry Andric RD_RP = 9, // Round toward Plus infinity 77*5ffd83dbSDimitry Andric RD_RM = 10, // Round toward Minus infinity 78*5ffd83dbSDimitry Andric RD_RN = 11, // Round to Nearest (ties to Even) 79*5ffd83dbSDimitry Andric RD_RA = 12, // Round to Nearest (ties to Away) 80*5ffd83dbSDimitry Andric UNKNOWN 81480093f4SDimitry Andric }; 82480093f4SDimitry Andric } 83480093f4SDimitry Andric 84*5ffd83dbSDimitry Andric inline static const char *VECondCodeToString(VECC::CondCode CC) { 85480093f4SDimitry Andric switch (CC) { 86480093f4SDimitry Andric case VECC::CC_IG: return "gt"; 87480093f4SDimitry Andric case VECC::CC_IL: return "lt"; 88480093f4SDimitry Andric case VECC::CC_INE: return "ne"; 89480093f4SDimitry Andric case VECC::CC_IEQ: return "eq"; 90480093f4SDimitry Andric case VECC::CC_IGE: return "ge"; 91480093f4SDimitry Andric case VECC::CC_ILE: return "le"; 92480093f4SDimitry Andric case VECC::CC_AF: return "af"; 93480093f4SDimitry Andric case VECC::CC_G: return "gt"; 94480093f4SDimitry Andric case VECC::CC_L: return "lt"; 95480093f4SDimitry Andric case VECC::CC_NE: return "ne"; 96480093f4SDimitry Andric case VECC::CC_EQ: return "eq"; 97480093f4SDimitry Andric case VECC::CC_GE: return "ge"; 98480093f4SDimitry Andric case VECC::CC_LE: return "le"; 99480093f4SDimitry Andric case VECC::CC_NUM: return "num"; 100480093f4SDimitry Andric case VECC::CC_NAN: return "nan"; 101480093f4SDimitry Andric case VECC::CC_GNAN: return "gtnan"; 102480093f4SDimitry Andric case VECC::CC_LNAN: return "ltnan"; 103480093f4SDimitry Andric case VECC::CC_NENAN: return "nenan"; 104480093f4SDimitry Andric case VECC::CC_EQNAN: return "eqnan"; 105480093f4SDimitry Andric case VECC::CC_GENAN: return "genan"; 106480093f4SDimitry Andric case VECC::CC_LENAN: return "lenan"; 107480093f4SDimitry Andric case VECC::CC_AT: return "at"; 108*5ffd83dbSDimitry Andric default: 109*5ffd83dbSDimitry Andric llvm_unreachable("Invalid cond code"); 110*5ffd83dbSDimitry Andric } 111*5ffd83dbSDimitry Andric } 112*5ffd83dbSDimitry Andric 113*5ffd83dbSDimitry Andric inline static VECC::CondCode stringToVEICondCode(StringRef S) { 114*5ffd83dbSDimitry Andric return StringSwitch<VECC::CondCode>(S) 115*5ffd83dbSDimitry Andric .Case("gt", VECC::CC_IG) 116*5ffd83dbSDimitry Andric .Case("lt", VECC::CC_IL) 117*5ffd83dbSDimitry Andric .Case("ne", VECC::CC_INE) 118*5ffd83dbSDimitry Andric .Case("eq", VECC::CC_IEQ) 119*5ffd83dbSDimitry Andric .Case("ge", VECC::CC_IGE) 120*5ffd83dbSDimitry Andric .Case("le", VECC::CC_ILE) 121*5ffd83dbSDimitry Andric .Case("af", VECC::CC_AF) 122*5ffd83dbSDimitry Andric .Case("at", VECC::CC_AT) 123*5ffd83dbSDimitry Andric .Case("", VECC::CC_AT) 124*5ffd83dbSDimitry Andric .Default(VECC::UNKNOWN); 125*5ffd83dbSDimitry Andric } 126*5ffd83dbSDimitry Andric 127*5ffd83dbSDimitry Andric inline static VECC::CondCode stringToVEFCondCode(StringRef S) { 128*5ffd83dbSDimitry Andric return StringSwitch<VECC::CondCode>(S) 129*5ffd83dbSDimitry Andric .Case("gt", VECC::CC_G) 130*5ffd83dbSDimitry Andric .Case("lt", VECC::CC_L) 131*5ffd83dbSDimitry Andric .Case("ne", VECC::CC_NE) 132*5ffd83dbSDimitry Andric .Case("eq", VECC::CC_EQ) 133*5ffd83dbSDimitry Andric .Case("ge", VECC::CC_GE) 134*5ffd83dbSDimitry Andric .Case("le", VECC::CC_LE) 135*5ffd83dbSDimitry Andric .Case("num", VECC::CC_NUM) 136*5ffd83dbSDimitry Andric .Case("nan", VECC::CC_NAN) 137*5ffd83dbSDimitry Andric .Case("gtnan", VECC::CC_GNAN) 138*5ffd83dbSDimitry Andric .Case("ltnan", VECC::CC_LNAN) 139*5ffd83dbSDimitry Andric .Case("nenan", VECC::CC_NENAN) 140*5ffd83dbSDimitry Andric .Case("eqnan", VECC::CC_EQNAN) 141*5ffd83dbSDimitry Andric .Case("genan", VECC::CC_GENAN) 142*5ffd83dbSDimitry Andric .Case("lenan", VECC::CC_LENAN) 143*5ffd83dbSDimitry Andric .Case("af", VECC::CC_AF) 144*5ffd83dbSDimitry Andric .Case("at", VECC::CC_AT) 145*5ffd83dbSDimitry Andric .Case("", VECC::CC_AT) 146*5ffd83dbSDimitry Andric .Default(VECC::UNKNOWN); 147*5ffd83dbSDimitry Andric } 148*5ffd83dbSDimitry Andric 149*5ffd83dbSDimitry Andric inline static unsigned VECondCodeToVal(VECC::CondCode CC) { 150*5ffd83dbSDimitry Andric switch (CC) { 151*5ffd83dbSDimitry Andric case VECC::CC_IG: 152*5ffd83dbSDimitry Andric return 1; 153*5ffd83dbSDimitry Andric case VECC::CC_IL: 154*5ffd83dbSDimitry Andric return 2; 155*5ffd83dbSDimitry Andric case VECC::CC_INE: 156*5ffd83dbSDimitry Andric return 3; 157*5ffd83dbSDimitry Andric case VECC::CC_IEQ: 158*5ffd83dbSDimitry Andric return 4; 159*5ffd83dbSDimitry Andric case VECC::CC_IGE: 160*5ffd83dbSDimitry Andric return 5; 161*5ffd83dbSDimitry Andric case VECC::CC_ILE: 162*5ffd83dbSDimitry Andric return 6; 163*5ffd83dbSDimitry Andric case VECC::CC_AF: 164*5ffd83dbSDimitry Andric return 0; 165*5ffd83dbSDimitry Andric case VECC::CC_G: 166*5ffd83dbSDimitry Andric return 1; 167*5ffd83dbSDimitry Andric case VECC::CC_L: 168*5ffd83dbSDimitry Andric return 2; 169*5ffd83dbSDimitry Andric case VECC::CC_NE: 170*5ffd83dbSDimitry Andric return 3; 171*5ffd83dbSDimitry Andric case VECC::CC_EQ: 172*5ffd83dbSDimitry Andric return 4; 173*5ffd83dbSDimitry Andric case VECC::CC_GE: 174*5ffd83dbSDimitry Andric return 5; 175*5ffd83dbSDimitry Andric case VECC::CC_LE: 176*5ffd83dbSDimitry Andric return 6; 177*5ffd83dbSDimitry Andric case VECC::CC_NUM: 178*5ffd83dbSDimitry Andric return 7; 179*5ffd83dbSDimitry Andric case VECC::CC_NAN: 180*5ffd83dbSDimitry Andric return 8; 181*5ffd83dbSDimitry Andric case VECC::CC_GNAN: 182*5ffd83dbSDimitry Andric return 9; 183*5ffd83dbSDimitry Andric case VECC::CC_LNAN: 184*5ffd83dbSDimitry Andric return 10; 185*5ffd83dbSDimitry Andric case VECC::CC_NENAN: 186*5ffd83dbSDimitry Andric return 11; 187*5ffd83dbSDimitry Andric case VECC::CC_EQNAN: 188*5ffd83dbSDimitry Andric return 12; 189*5ffd83dbSDimitry Andric case VECC::CC_GENAN: 190*5ffd83dbSDimitry Andric return 13; 191*5ffd83dbSDimitry Andric case VECC::CC_LENAN: 192*5ffd83dbSDimitry Andric return 14; 193*5ffd83dbSDimitry Andric case VECC::CC_AT: 194*5ffd83dbSDimitry Andric return 15; 195*5ffd83dbSDimitry Andric default: 196*5ffd83dbSDimitry Andric llvm_unreachable("Invalid cond code"); 197*5ffd83dbSDimitry Andric } 198*5ffd83dbSDimitry Andric } 199*5ffd83dbSDimitry Andric 200*5ffd83dbSDimitry Andric inline static VECC::CondCode VEValToCondCode(unsigned Val, bool IsInteger) { 201*5ffd83dbSDimitry Andric if (IsInteger) { 202*5ffd83dbSDimitry Andric switch (Val) { 203*5ffd83dbSDimitry Andric case 0: 204*5ffd83dbSDimitry Andric return VECC::CC_AF; 205*5ffd83dbSDimitry Andric case 1: 206*5ffd83dbSDimitry Andric return VECC::CC_IG; 207*5ffd83dbSDimitry Andric case 2: 208*5ffd83dbSDimitry Andric return VECC::CC_IL; 209*5ffd83dbSDimitry Andric case 3: 210*5ffd83dbSDimitry Andric return VECC::CC_INE; 211*5ffd83dbSDimitry Andric case 4: 212*5ffd83dbSDimitry Andric return VECC::CC_IEQ; 213*5ffd83dbSDimitry Andric case 5: 214*5ffd83dbSDimitry Andric return VECC::CC_IGE; 215*5ffd83dbSDimitry Andric case 6: 216*5ffd83dbSDimitry Andric return VECC::CC_ILE; 217*5ffd83dbSDimitry Andric case 15: 218*5ffd83dbSDimitry Andric return VECC::CC_AT; 219*5ffd83dbSDimitry Andric } 220*5ffd83dbSDimitry Andric } else { 221*5ffd83dbSDimitry Andric switch (Val) { 222*5ffd83dbSDimitry Andric case 0: 223*5ffd83dbSDimitry Andric return VECC::CC_AF; 224*5ffd83dbSDimitry Andric case 1: 225*5ffd83dbSDimitry Andric return VECC::CC_G; 226*5ffd83dbSDimitry Andric case 2: 227*5ffd83dbSDimitry Andric return VECC::CC_L; 228*5ffd83dbSDimitry Andric case 3: 229*5ffd83dbSDimitry Andric return VECC::CC_NE; 230*5ffd83dbSDimitry Andric case 4: 231*5ffd83dbSDimitry Andric return VECC::CC_EQ; 232*5ffd83dbSDimitry Andric case 5: 233*5ffd83dbSDimitry Andric return VECC::CC_GE; 234*5ffd83dbSDimitry Andric case 6: 235*5ffd83dbSDimitry Andric return VECC::CC_LE; 236*5ffd83dbSDimitry Andric case 7: 237*5ffd83dbSDimitry Andric return VECC::CC_NUM; 238*5ffd83dbSDimitry Andric case 8: 239*5ffd83dbSDimitry Andric return VECC::CC_NAN; 240*5ffd83dbSDimitry Andric case 9: 241*5ffd83dbSDimitry Andric return VECC::CC_GNAN; 242*5ffd83dbSDimitry Andric case 10: 243*5ffd83dbSDimitry Andric return VECC::CC_LNAN; 244*5ffd83dbSDimitry Andric case 11: 245*5ffd83dbSDimitry Andric return VECC::CC_NENAN; 246*5ffd83dbSDimitry Andric case 12: 247*5ffd83dbSDimitry Andric return VECC::CC_EQNAN; 248*5ffd83dbSDimitry Andric case 13: 249*5ffd83dbSDimitry Andric return VECC::CC_GENAN; 250*5ffd83dbSDimitry Andric case 14: 251*5ffd83dbSDimitry Andric return VECC::CC_LENAN; 252*5ffd83dbSDimitry Andric case 15: 253*5ffd83dbSDimitry Andric return VECC::CC_AT; 254*5ffd83dbSDimitry Andric } 255480093f4SDimitry Andric } 256480093f4SDimitry Andric llvm_unreachable("Invalid cond code"); 257480093f4SDimitry Andric } 258480093f4SDimitry Andric 259*5ffd83dbSDimitry Andric inline static const char *VERDToString(VERD::RoundingMode R) { 260*5ffd83dbSDimitry Andric switch (R) { 261*5ffd83dbSDimitry Andric case VERD::RD_NONE: 262*5ffd83dbSDimitry Andric return ""; 263*5ffd83dbSDimitry Andric case VERD::RD_RZ: 264*5ffd83dbSDimitry Andric return ".rz"; 265*5ffd83dbSDimitry Andric case VERD::RD_RP: 266*5ffd83dbSDimitry Andric return ".rp"; 267*5ffd83dbSDimitry Andric case VERD::RD_RM: 268*5ffd83dbSDimitry Andric return ".rm"; 269*5ffd83dbSDimitry Andric case VERD::RD_RN: 270*5ffd83dbSDimitry Andric return ".rn"; 271*5ffd83dbSDimitry Andric case VERD::RD_RA: 272*5ffd83dbSDimitry Andric return ".ra"; 273*5ffd83dbSDimitry Andric default: 274*5ffd83dbSDimitry Andric llvm_unreachable("Invalid branch predicate"); 275*5ffd83dbSDimitry Andric } 276480093f4SDimitry Andric } 277480093f4SDimitry Andric 278*5ffd83dbSDimitry Andric inline static VERD::RoundingMode stringToVERD(StringRef S) { 279*5ffd83dbSDimitry Andric return StringSwitch<VERD::RoundingMode>(S) 280*5ffd83dbSDimitry Andric .Case("", VERD::RD_NONE) 281*5ffd83dbSDimitry Andric .Case(".rz", VERD::RD_RZ) 282*5ffd83dbSDimitry Andric .Case(".rp", VERD::RD_RP) 283*5ffd83dbSDimitry Andric .Case(".rm", VERD::RD_RM) 284*5ffd83dbSDimitry Andric .Case(".rn", VERD::RD_RN) 285*5ffd83dbSDimitry Andric .Case(".ra", VERD::RD_RA) 286*5ffd83dbSDimitry Andric .Default(VERD::UNKNOWN); 287480093f4SDimitry Andric } 288480093f4SDimitry Andric 289*5ffd83dbSDimitry Andric inline static unsigned VERDToVal(VERD::RoundingMode R) { 290*5ffd83dbSDimitry Andric switch (R) { 291*5ffd83dbSDimitry Andric case VERD::RD_NONE: 292*5ffd83dbSDimitry Andric case VERD::RD_RZ: 293*5ffd83dbSDimitry Andric case VERD::RD_RP: 294*5ffd83dbSDimitry Andric case VERD::RD_RM: 295*5ffd83dbSDimitry Andric case VERD::RD_RN: 296*5ffd83dbSDimitry Andric case VERD::RD_RA: 297*5ffd83dbSDimitry Andric return static_cast<unsigned>(R); 298*5ffd83dbSDimitry Andric default: 299*5ffd83dbSDimitry Andric break; 300*5ffd83dbSDimitry Andric } 301*5ffd83dbSDimitry Andric llvm_unreachable("Invalid branch predicates"); 302*5ffd83dbSDimitry Andric } 303*5ffd83dbSDimitry Andric 304*5ffd83dbSDimitry Andric inline static VERD::RoundingMode VEValToRD(unsigned Val) { 305*5ffd83dbSDimitry Andric switch (Val) { 306*5ffd83dbSDimitry Andric case static_cast<unsigned>(VERD::RD_NONE): 307*5ffd83dbSDimitry Andric return VERD::RD_NONE; 308*5ffd83dbSDimitry Andric case static_cast<unsigned>(VERD::RD_RZ): 309*5ffd83dbSDimitry Andric return VERD::RD_RZ; 310*5ffd83dbSDimitry Andric case static_cast<unsigned>(VERD::RD_RP): 311*5ffd83dbSDimitry Andric return VERD::RD_RP; 312*5ffd83dbSDimitry Andric case static_cast<unsigned>(VERD::RD_RM): 313*5ffd83dbSDimitry Andric return VERD::RD_RM; 314*5ffd83dbSDimitry Andric case static_cast<unsigned>(VERD::RD_RN): 315*5ffd83dbSDimitry Andric return VERD::RD_RN; 316*5ffd83dbSDimitry Andric case static_cast<unsigned>(VERD::RD_RA): 317*5ffd83dbSDimitry Andric return VERD::RD_RA; 318*5ffd83dbSDimitry Andric default: 319*5ffd83dbSDimitry Andric break; 320*5ffd83dbSDimitry Andric } 321*5ffd83dbSDimitry Andric llvm_unreachable("Invalid branch predicates"); 322*5ffd83dbSDimitry Andric } 323*5ffd83dbSDimitry Andric 324*5ffd83dbSDimitry Andric // MImm - Special immediate value of sequential bit stream of 0 or 1. 325*5ffd83dbSDimitry Andric // See VEInstrInfo.td for details. 326*5ffd83dbSDimitry Andric inline static bool isMImmVal(uint64_t Val) { 327*5ffd83dbSDimitry Andric if (Val == 0) { 328*5ffd83dbSDimitry Andric // (0)1 is 0 329*5ffd83dbSDimitry Andric return true; 330*5ffd83dbSDimitry Andric } 331*5ffd83dbSDimitry Andric if (isMask_64(Val)) { 332*5ffd83dbSDimitry Andric // (m)0 patterns 333*5ffd83dbSDimitry Andric return true; 334*5ffd83dbSDimitry Andric } 335*5ffd83dbSDimitry Andric // (m)1 patterns 336*5ffd83dbSDimitry Andric return (Val & (1UL << 63)) && isShiftedMask_64(Val); 337*5ffd83dbSDimitry Andric } 338*5ffd83dbSDimitry Andric 339*5ffd83dbSDimitry Andric inline static bool isMImm32Val(uint32_t Val) { 340*5ffd83dbSDimitry Andric if (Val == 0) { 341*5ffd83dbSDimitry Andric // (0)1 is 0 342*5ffd83dbSDimitry Andric return true; 343*5ffd83dbSDimitry Andric } 344*5ffd83dbSDimitry Andric if (isMask_32(Val)) { 345*5ffd83dbSDimitry Andric // (m)0 patterns 346*5ffd83dbSDimitry Andric return true; 347*5ffd83dbSDimitry Andric } 348*5ffd83dbSDimitry Andric // (m)1 patterns 349*5ffd83dbSDimitry Andric return (Val & (1 << 31)) && isShiftedMask_32(Val); 350*5ffd83dbSDimitry Andric } 351*5ffd83dbSDimitry Andric 352*5ffd83dbSDimitry Andric inline unsigned M0(unsigned Val) { return Val + 64; } 353*5ffd83dbSDimitry Andric inline unsigned M1(unsigned Val) { return Val; } 354*5ffd83dbSDimitry Andric 355480093f4SDimitry Andric } // namespace llvm 356480093f4SDimitry Andric #endif 357