diff options
Diffstat (limited to 'llvm/lib/Target/VE/VE.h')
-rw-r--r-- | llvm/lib/Target/VE/VE.h | 293 |
1 files changed, 270 insertions, 23 deletions
diff --git a/llvm/lib/Target/VE/VE.h b/llvm/lib/Target/VE/VE.h index 9b61f2b63f36..7ed7797cbb83 100644 --- a/llvm/lib/Target/VE/VE.h +++ b/llvm/lib/Target/VE/VE.h @@ -15,6 +15,7 @@ #define LLVM_LIB_TARGET_VE_VE_H #include "MCTargetDesc/VEMCTargetDesc.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetMachine.h" @@ -37,36 +38,50 @@ namespace llvm { // Enums corresponding to VE condition codes, both icc's and fcc's. These // values must be kept in sync with the ones in the .td file. namespace VECC { -enum CondCodes { +enum CondCode { // Integer comparison - CC_IG = 0, // Greater - CC_IL = 1, // Less + CC_IG = 0, // Greater + CC_IL = 1, // Less CC_INE = 2, // Not Equal CC_IEQ = 3, // Equal CC_IGE = 4, // Greater or Equal CC_ILE = 5, // Less or Equal // Floating point comparison - CC_AF = 0 + 6, // Never - CC_G = 1 + 6, // Greater - CC_L = 2 + 6, // Less - CC_NE = 3 + 6, // Not Equal - CC_EQ = 4 + 6, // Equal - CC_GE = 5 + 6, // Greater or Equal - CC_LE = 6 + 6, // Less or Equal - CC_NUM = 7 + 6, // Number - CC_NAN = 8 + 6, // NaN - CC_GNAN = 9 + 6, // Greater or NaN - CC_LNAN = 10 + 6, // Less or NaN + CC_AF = 0 + 6, // Never + CC_G = 1 + 6, // Greater + CC_L = 2 + 6, // Less + CC_NE = 3 + 6, // Not Equal + CC_EQ = 4 + 6, // Equal + CC_GE = 5 + 6, // Greater or Equal + CC_LE = 6 + 6, // Less or Equal + CC_NUM = 7 + 6, // Number + CC_NAN = 8 + 6, // NaN + CC_GNAN = 9 + 6, // Greater or NaN + CC_LNAN = 10 + 6, // Less or NaN CC_NENAN = 11 + 6, // Not Equal or NaN CC_EQNAN = 12 + 6, // Equal or NaN CC_GENAN = 13 + 6, // Greater or Equal or NaN CC_LENAN = 14 + 6, // Less or Equal or NaN - CC_AT = 15 + 6, // Always + CC_AT = 15 + 6, // Always + UNKNOWN +}; +} +// Enums corresponding to VE Rounding Mode. These values must be kept in +// sync with the ones in the .td file. +namespace VERD { +enum RoundingMode { + RD_NONE = 0, // According to PSW + RD_RZ = 8, // Round toward Zero + RD_RP = 9, // Round toward Plus infinity + RD_RM = 10, // Round toward Minus infinity + RD_RN = 11, // Round to Nearest (ties to Even) + RD_RA = 12, // Round to Nearest (ties to Away) + UNKNOWN }; } -inline static const char *VECondCodeToString(VECC::CondCodes CC) { +inline static const char *VECondCodeToString(VECC::CondCode CC) { switch (CC) { case VECC::CC_IG: return "gt"; case VECC::CC_IL: return "lt"; @@ -90,20 +105,252 @@ inline static const char *VECondCodeToString(VECC::CondCodes CC) { case VECC::CC_GENAN: return "genan"; case VECC::CC_LENAN: return "lenan"; case VECC::CC_AT: return "at"; + default: + llvm_unreachable("Invalid cond code"); + } +} + +inline static VECC::CondCode stringToVEICondCode(StringRef S) { + return StringSwitch<VECC::CondCode>(S) + .Case("gt", VECC::CC_IG) + .Case("lt", VECC::CC_IL) + .Case("ne", VECC::CC_INE) + .Case("eq", VECC::CC_IEQ) + .Case("ge", VECC::CC_IGE) + .Case("le", VECC::CC_ILE) + .Case("af", VECC::CC_AF) + .Case("at", VECC::CC_AT) + .Case("", VECC::CC_AT) + .Default(VECC::UNKNOWN); +} + +inline static VECC::CondCode stringToVEFCondCode(StringRef S) { + return StringSwitch<VECC::CondCode>(S) + .Case("gt", VECC::CC_G) + .Case("lt", VECC::CC_L) + .Case("ne", VECC::CC_NE) + .Case("eq", VECC::CC_EQ) + .Case("ge", VECC::CC_GE) + .Case("le", VECC::CC_LE) + .Case("num", VECC::CC_NUM) + .Case("nan", VECC::CC_NAN) + .Case("gtnan", VECC::CC_GNAN) + .Case("ltnan", VECC::CC_LNAN) + .Case("nenan", VECC::CC_NENAN) + .Case("eqnan", VECC::CC_EQNAN) + .Case("genan", VECC::CC_GENAN) + .Case("lenan", VECC::CC_LENAN) + .Case("af", VECC::CC_AF) + .Case("at", VECC::CC_AT) + .Case("", VECC::CC_AT) + .Default(VECC::UNKNOWN); +} + +inline static unsigned VECondCodeToVal(VECC::CondCode CC) { + switch (CC) { + case VECC::CC_IG: + return 1; + case VECC::CC_IL: + return 2; + case VECC::CC_INE: + return 3; + case VECC::CC_IEQ: + return 4; + case VECC::CC_IGE: + return 5; + case VECC::CC_ILE: + return 6; + case VECC::CC_AF: + return 0; + case VECC::CC_G: + return 1; + case VECC::CC_L: + return 2; + case VECC::CC_NE: + return 3; + case VECC::CC_EQ: + return 4; + case VECC::CC_GE: + return 5; + case VECC::CC_LE: + return 6; + case VECC::CC_NUM: + return 7; + case VECC::CC_NAN: + return 8; + case VECC::CC_GNAN: + return 9; + case VECC::CC_LNAN: + return 10; + case VECC::CC_NENAN: + return 11; + case VECC::CC_EQNAN: + return 12; + case VECC::CC_GENAN: + return 13; + case VECC::CC_LENAN: + return 14; + case VECC::CC_AT: + return 15; + default: + llvm_unreachable("Invalid cond code"); + } +} + +inline static VECC::CondCode VEValToCondCode(unsigned Val, bool IsInteger) { + if (IsInteger) { + switch (Val) { + case 0: + return VECC::CC_AF; + case 1: + return VECC::CC_IG; + case 2: + return VECC::CC_IL; + case 3: + return VECC::CC_INE; + case 4: + return VECC::CC_IEQ; + case 5: + return VECC::CC_IGE; + case 6: + return VECC::CC_ILE; + case 15: + return VECC::CC_AT; + } + } else { + switch (Val) { + case 0: + return VECC::CC_AF; + case 1: + return VECC::CC_G; + case 2: + return VECC::CC_L; + case 3: + return VECC::CC_NE; + case 4: + return VECC::CC_EQ; + case 5: + return VECC::CC_GE; + case 6: + return VECC::CC_LE; + case 7: + return VECC::CC_NUM; + case 8: + return VECC::CC_NAN; + case 9: + return VECC::CC_GNAN; + case 10: + return VECC::CC_LNAN; + case 11: + return VECC::CC_NENAN; + case 12: + return VECC::CC_EQNAN; + case 13: + return VECC::CC_GENAN; + case 14: + return VECC::CC_LENAN; + case 15: + return VECC::CC_AT; + } } llvm_unreachable("Invalid cond code"); } -// Different to Hi_32/Lo_32 the HI32 and LO32 functions -// preserve the correct numerical value -// on the LLVM data type for MC immediates (int64_t). -inline static int64_t HI32(int64_t imm) { - return (int32_t)(imm >> 32); +inline static const char *VERDToString(VERD::RoundingMode R) { + switch (R) { + case VERD::RD_NONE: + return ""; + case VERD::RD_RZ: + return ".rz"; + case VERD::RD_RP: + return ".rp"; + case VERD::RD_RM: + return ".rm"; + case VERD::RD_RN: + return ".rn"; + case VERD::RD_RA: + return ".ra"; + default: + llvm_unreachable("Invalid branch predicate"); + } } -inline static int64_t LO32(int64_t imm) { - return (int32_t)(imm); +inline static VERD::RoundingMode stringToVERD(StringRef S) { + return StringSwitch<VERD::RoundingMode>(S) + .Case("", VERD::RD_NONE) + .Case(".rz", VERD::RD_RZ) + .Case(".rp", VERD::RD_RP) + .Case(".rm", VERD::RD_RM) + .Case(".rn", VERD::RD_RN) + .Case(".ra", VERD::RD_RA) + .Default(VERD::UNKNOWN); } +inline static unsigned VERDToVal(VERD::RoundingMode R) { + switch (R) { + case VERD::RD_NONE: + case VERD::RD_RZ: + case VERD::RD_RP: + case VERD::RD_RM: + case VERD::RD_RN: + case VERD::RD_RA: + return static_cast<unsigned>(R); + default: + break; + } + llvm_unreachable("Invalid branch predicates"); +} + +inline static VERD::RoundingMode VEValToRD(unsigned Val) { + switch (Val) { + case static_cast<unsigned>(VERD::RD_NONE): + return VERD::RD_NONE; + case static_cast<unsigned>(VERD::RD_RZ): + return VERD::RD_RZ; + case static_cast<unsigned>(VERD::RD_RP): + return VERD::RD_RP; + case static_cast<unsigned>(VERD::RD_RM): + return VERD::RD_RM; + case static_cast<unsigned>(VERD::RD_RN): + return VERD::RD_RN; + case static_cast<unsigned>(VERD::RD_RA): + return VERD::RD_RA; + default: + break; + } + llvm_unreachable("Invalid branch predicates"); +} + +// MImm - Special immediate value of sequential bit stream of 0 or 1. +// See VEInstrInfo.td for details. +inline static bool isMImmVal(uint64_t Val) { + if (Val == 0) { + // (0)1 is 0 + return true; + } + if (isMask_64(Val)) { + // (m)0 patterns + return true; + } + // (m)1 patterns + return (Val & (1UL << 63)) && isShiftedMask_64(Val); +} + +inline static bool isMImm32Val(uint32_t Val) { + if (Val == 0) { + // (0)1 is 0 + return true; + } + if (isMask_32(Val)) { + // (m)0 patterns + return true; + } + // (m)1 patterns + return (Val & (1 << 31)) && isShiftedMask_32(Val); +} + +inline unsigned M0(unsigned Val) { return Val + 64; } +inline unsigned M1(unsigned Val) { return Val; } + } // namespace llvm #endif |