#ifndef LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
#define LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/MC/SubtargetFeature.h"
#include "MCTargetDesc/ARMMCTargetDesc.h"
namespace llvm {
namespace ARMCC {
enum CondCodes { EQ, NE, HS, LO, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL };
inline static CondCodes getOppositeCondition(CondCodes CC) {
switch (CC) {
default: llvm_unreachable("Unknown condition code");
case EQ: return NE;
case NE: return EQ;
case HS: return LO;
case LO: return HS;
case MI: return PL;
case PL: return MI;
case VS: return VC;
case VC: return VS;
case HI: return LS;
case LS: return HI;
case GE: return LT;
case LT: return GE;
case GT: return LE;
case LE: return GT;
}
}
inline static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC) {
switch (CC) {
default: return ARMCC::AL;
case ARMCC::EQ: return ARMCC::EQ;
case ARMCC::NE: return ARMCC::NE;
case ARMCC::HS: return ARMCC::LS;
case ARMCC::LO: return ARMCC::HI;
case ARMCC::HI: return ARMCC::LO;
case ARMCC::LS: return ARMCC::HS;
case ARMCC::GE: return ARMCC::LE;
case ARMCC::LT: return ARMCC::GT;
case ARMCC::GT: return ARMCC::LT;
case ARMCC::LE: return ARMCC::GE;
}
}
}
namespace ARMVCC {
enum VPTCodes {
None = 0,
Then,
Else
};
}
namespace ARM {
enum class PredBlockMask {
T = 0b1000,
TT = 0b0100,
TE = 0b1100,
TTT = 0b0010,
TTE = 0b0110,
TEE = 0b1110,
TET = 0b1010,
TTTT = 0b0001,
TTTE = 0b0011,
TTEE = 0b0111,
TTET = 0b0101,
TEEE = 0b1111,
TEET = 0b1101,
TETT = 0b1001,
TETE = 0b1011
};
}
ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask,
ARMVCC::VPTCodes Kind);
inline static const char *ARMVPTPredToString(ARMVCC::VPTCodes CC) {
switch (CC) {
case ARMVCC::None: return "none";
case ARMVCC::Then: return "t";
case ARMVCC::Else: return "e";
}
llvm_unreachable("Unknown VPT code");
}
inline static unsigned ARMVectorCondCodeFromString(StringRef CC) {
return StringSwitch<unsigned>(CC.lower())
.Case("t", ARMVCC::Then)
.Case("e", ARMVCC::Else)
.Default(~0U);
}
inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
switch (CC) {
case ARMCC::EQ: return "eq";
case ARMCC::NE: return "ne";
case ARMCC::HS: return "hs";
case ARMCC::LO: return "lo";
case ARMCC::MI: return "mi";
case ARMCC::PL: return "pl";
case ARMCC::VS: return "vs";
case ARMCC::VC: return "vc";
case ARMCC::HI: return "hi";
case ARMCC::LS: return "ls";
case ARMCC::GE: return "ge";
case ARMCC::LT: return "lt";
case ARMCC::GT: return "gt";
case ARMCC::LE: return "le";
case ARMCC::AL: return "al";
}
llvm_unreachable("Unknown condition code");
}
inline static unsigned ARMCondCodeFromString(StringRef CC) {
return StringSwitch<unsigned>(CC.lower())
.Case("eq", ARMCC::EQ)
.Case("ne", ARMCC::NE)
.Case("hs", ARMCC::HS)
.Case("cs", ARMCC::HS)
.Case("lo", ARMCC::LO)
.Case("cc", ARMCC::LO)
.Case("mi", ARMCC::MI)
.Case("pl", ARMCC::PL)
.Case("vs", ARMCC::VS)
.Case("vc", ARMCC::VC)
.Case("hi", ARMCC::HI)
.Case("ls", ARMCC::LS)
.Case("ge", ARMCC::GE)
.Case("lt", ARMCC::LT)
.Case("gt", ARMCC::GT)
.Case("le", ARMCC::LE)
.Case("al", ARMCC::AL)
.Default(~0U);
}
namespace ARMSysReg {
struct MClassSysReg {
const char *Name;
uint16_t M1Encoding12;
uint16_t M2M3Encoding8;
uint16_t Encoding;
FeatureBitset FeaturesRequired;
bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const {
return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
}
bool isInRequiredFeatures(FeatureBitset TestFeatures) const {
return (FeaturesRequired & TestFeatures) == TestFeatures;
}
};
#define GET_MCLASSSYSREG_DECL
#include "ARMGenSystemRegister.inc"
const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm);
const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm);
const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm);
}
namespace ARMBankedReg {
struct BankedReg {
const char *Name;
uint16_t Encoding;
};
#define GET_BANKEDREG_DECL
#include "ARMGenSystemRegister.inc"
}
}
#endif