diff options
Diffstat (limited to 'llvm/lib/Target/ARM/Utils')
-rw-r--r-- | llvm/lib/Target/ARM/Utils/ARMBaseInfo.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/Utils/ARMBaseInfo.h | 66 |
2 files changed, 64 insertions, 33 deletions
diff --git a/llvm/lib/Target/ARM/Utils/ARMBaseInfo.cpp b/llvm/lib/Target/ARM/Utils/ARMBaseInfo.cpp index 4ace61cccd0f6..3356d56481e57 100644 --- a/llvm/lib/Target/ARM/Utils/ARMBaseInfo.cpp +++ b/llvm/lib/Target/ARM/Utils/ARMBaseInfo.cpp @@ -15,6 +15,37 @@ using namespace llvm; namespace llvm { +ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask, + ARMVCC::VPTCodes Kind) { + using PredBlockMask = ARM::PredBlockMask; + assert(Kind != ARMVCC::None && "Cannot expand a mask with None!"); + assert(countTrailingZeros((unsigned)BlockMask) != 0 && + "Mask is already full"); + + auto ChooseMask = [&](PredBlockMask AddedThen, PredBlockMask AddedElse) { + return Kind == ARMVCC::Then ? AddedThen : AddedElse; + }; + + switch (BlockMask) { + case PredBlockMask::T: + return ChooseMask(PredBlockMask::TT, PredBlockMask::TE); + case PredBlockMask::TT: + return ChooseMask(PredBlockMask::TTT, PredBlockMask::TTE); + case PredBlockMask::TE: + return ChooseMask(PredBlockMask::TET, PredBlockMask::TEE); + case PredBlockMask::TTT: + return ChooseMask(PredBlockMask::TTTT, PredBlockMask::TTTE); + case PredBlockMask::TTE: + return ChooseMask(PredBlockMask::TTET, PredBlockMask::TTEE); + case PredBlockMask::TET: + return ChooseMask(PredBlockMask::TETT, PredBlockMask::TETE); + case PredBlockMask::TEE: + return ChooseMask(PredBlockMask::TEET, PredBlockMask::TEEE); + default: + llvm_unreachable("Unknown Mask"); + } +} + namespace ARMSysReg { // lookup system register using 12-bit SYSm value. diff --git a/llvm/lib/Target/ARM/Utils/ARMBaseInfo.h b/llvm/lib/Target/ARM/Utils/ARMBaseInfo.h index 27605422983d8..80b7276adb4e8 100644 --- a/llvm/lib/Target/ARM/Utils/ARMBaseInfo.h +++ b/llvm/lib/Target/ARM/Utils/ARMBaseInfo.h @@ -91,41 +91,41 @@ namespace ARMVCC { Then, Else }; - - enum VPTMaskValue { - T = 8, // 0b1000 - TT = 4, // 0b0100 - TE = 12, // 0b1100 - TTT = 2, // 0b0010 - TTE = 6, // 0b0110 - TEE = 10, // 0b1010 - TET = 14, // 0b1110 - TTTT = 1, // 0b0001 - TTTE = 3, // 0b0011 - TTEE = 5, // 0b0101 - TTET = 7, // 0b0111 - TEEE = 9, // 0b1001 - TEET = 11, // 0b1011 - TETT = 13, // 0b1101 - TETE = 15 // 0b1111 +} // namespace ARMVCC + +namespace ARM { + /// Mask values for IT and VPT Blocks, to be used by MCOperands. + /// Note that this is different from the "real" encoding used by the + /// instructions. In this encoding, the lowest set bit indicates the end of + /// the encoding, and above that, "1" indicates an else, while "0" indicates + /// a then. + /// Tx = x100 + /// Txy = xy10 + /// Txyz = xyz1 + 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 }; -} +} // namespace ARM -inline static unsigned getARMVPTBlockMask(unsigned NumInsts) { - switch (NumInsts) { - case 1: - return ARMVCC::T; - case 2: - return ARMVCC::TT; - case 3: - return ARMVCC::TTT; - case 4: - return ARMVCC::TTTT; - default: - break; - }; - llvm_unreachable("Unexpected number of instruction in a VPT block"); -} +// Expands a PredBlockMask by adding an E or a T at the end, depending on Kind. +// e.g ExpandPredBlockMask(T, Then) = TT, ExpandPredBlockMask(TT, Else) = TTE, +// and so on. +ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask, + ARMVCC::VPTCodes Kind); inline static const char *ARMVPTPredToString(ARMVCC::VPTCodes CC) { switch (CC) { |