Home | History | Annotate | Line # | Download | only in VE
      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