forked from OSchip/llvm-project
[AArch64][AsmParser] NFC: Generalize LogicalImm[Not](32|64) code
Summary: All variants of isLogicalImm[Not](32|64) can be combined into a single templated function, same for printLogicalImm(32|64). By making it use a template instead, further SVE patches can use it for other data types as well (e.g. 8, 16 bits). Reviewers: fhahn, rengolin, aadg, echristo, kristof.beyls, samparker Reviewed By: samparker Subscribers: aemerson, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D42294 llvm-svn: 323646
This commit is contained in:
parent
de6fad6935
commit
a1c259c22c
|
@ -501,27 +501,35 @@ def logical_imm64_XFORM : SDNodeXForm<imm, [{
|
|||
let DiagnosticType = "LogicalSecondSource" in {
|
||||
def LogicalImm32Operand : AsmOperandClass {
|
||||
let Name = "LogicalImm32";
|
||||
let PredicateMethod = "isLogicalImm<int32_t>";
|
||||
let RenderMethod = "addLogicalImmOperands<int32_t>";
|
||||
}
|
||||
def LogicalImm64Operand : AsmOperandClass {
|
||||
let Name = "LogicalImm64";
|
||||
let PredicateMethod = "isLogicalImm<int64_t>";
|
||||
let RenderMethod = "addLogicalImmOperands<int64_t>";
|
||||
}
|
||||
def LogicalImm32NotOperand : AsmOperandClass {
|
||||
let Name = "LogicalImm32Not";
|
||||
let PredicateMethod = "isLogicalImm<int32_t>";
|
||||
let RenderMethod = "addLogicalImmNotOperands<int32_t>";
|
||||
}
|
||||
def LogicalImm64NotOperand : AsmOperandClass {
|
||||
let Name = "LogicalImm64Not";
|
||||
let PredicateMethod = "isLogicalImm<int64_t>";
|
||||
let RenderMethod = "addLogicalImmNotOperands<int64_t>";
|
||||
}
|
||||
}
|
||||
def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
|
||||
return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
|
||||
}], logical_imm32_XFORM> {
|
||||
let PrintMethod = "printLogicalImm32";
|
||||
let PrintMethod = "printLogicalImm<int32_t>";
|
||||
let ParserMatchClass = LogicalImm32Operand;
|
||||
}
|
||||
def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
|
||||
return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
|
||||
}], logical_imm64_XFORM> {
|
||||
let PrintMethod = "printLogicalImm64";
|
||||
let PrintMethod = "printLogicalImm<int64_t>";
|
||||
let ParserMatchClass = LogicalImm64Operand;
|
||||
}
|
||||
def logical_imm32_not : Operand<i32> {
|
||||
|
|
|
@ -555,45 +555,23 @@ public:
|
|||
return (Val >= N && Val <= M);
|
||||
}
|
||||
|
||||
bool isLogicalImm32() const {
|
||||
// NOTE: Also used for isLogicalImmNot as anything that can be represented as
|
||||
// a logical immediate can always be represented when inverted.
|
||||
template <typename T>
|
||||
bool isLogicalImm() const {
|
||||
if (!isImm())
|
||||
return false;
|
||||
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
|
||||
if (!MCE)
|
||||
return false;
|
||||
|
||||
int64_t Val = MCE->getValue();
|
||||
if (Val >> 32 != 0 && Val >> 32 != ~0LL)
|
||||
int64_t SVal = typename std::make_signed<T>::type(Val);
|
||||
int64_t UVal = typename std::make_unsigned<T>::type(Val);
|
||||
if (Val != SVal && Val != UVal)
|
||||
return false;
|
||||
Val &= 0xFFFFFFFF;
|
||||
return AArch64_AM::isLogicalImmediate(Val, 32);
|
||||
}
|
||||
|
||||
bool isLogicalImm64() const {
|
||||
if (!isImm())
|
||||
return false;
|
||||
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
|
||||
if (!MCE)
|
||||
return false;
|
||||
return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64);
|
||||
}
|
||||
|
||||
bool isLogicalImm32Not() const {
|
||||
if (!isImm())
|
||||
return false;
|
||||
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
|
||||
if (!MCE)
|
||||
return false;
|
||||
int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
|
||||
return AArch64_AM::isLogicalImmediate(Val, 32);
|
||||
}
|
||||
|
||||
bool isLogicalImm64Not() const {
|
||||
if (!isImm())
|
||||
return false;
|
||||
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
|
||||
if (!MCE)
|
||||
return false;
|
||||
return AArch64_AM::isLogicalImmediate(~MCE->getValue(), 64);
|
||||
return AArch64_AM::isLogicalImmediate(UVal, sizeof(T) * 8);
|
||||
}
|
||||
|
||||
bool isShiftedImm() const { return Kind == k_ShiftedImm; }
|
||||
|
@ -1378,34 +1356,21 @@ public:
|
|||
Inst.addOperand(MCOperand::createImm(MCE->getValue()));
|
||||
}
|
||||
|
||||
void addLogicalImm32Operands(MCInst &Inst, unsigned N) const {
|
||||
template <typename T>
|
||||
void addLogicalImmOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
|
||||
uint64_t encoding =
|
||||
AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32);
|
||||
typename std::make_unsigned<T>::type Val = MCE->getValue();
|
||||
uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8);
|
||||
Inst.addOperand(MCOperand::createImm(encoding));
|
||||
}
|
||||
|
||||
void addLogicalImm64Operands(MCInst &Inst, unsigned N) const {
|
||||
template <typename T>
|
||||
void addLogicalImmNotOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
|
||||
uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
|
||||
Inst.addOperand(MCOperand::createImm(encoding));
|
||||
}
|
||||
|
||||
void addLogicalImm32NotOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
|
||||
int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
|
||||
uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, 32);
|
||||
Inst.addOperand(MCOperand::createImm(encoding));
|
||||
}
|
||||
|
||||
void addLogicalImm64NotOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
|
||||
uint64_t encoding =
|
||||
AArch64_AM::encodeLogicalImmediate(~MCE->getValue(), 64);
|
||||
typename std::make_unsigned<T>::type Val = ~MCE->getValue();
|
||||
uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8);
|
||||
Inst.addOperand(MCOperand::createImm(encoding));
|
||||
}
|
||||
|
||||
|
|
|
@ -907,20 +907,13 @@ void AArch64InstPrinter::printAddSubImm(const MCInst *MI, unsigned OpNum,
|
|||
}
|
||||
}
|
||||
|
||||
void AArch64InstPrinter::printLogicalImm32(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
template <typename T>
|
||||
void AArch64InstPrinter::printLogicalImm(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
uint64_t Val = MI->getOperand(OpNum).getImm();
|
||||
O << "#0x";
|
||||
O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 32));
|
||||
}
|
||||
|
||||
void AArch64InstPrinter::printLogicalImm64(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
uint64_t Val = MI->getOperand(OpNum).getImm();
|
||||
O << "#0x";
|
||||
O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 64));
|
||||
O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 8 * sizeof(T)));
|
||||
}
|
||||
|
||||
void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum,
|
||||
|
@ -1369,4 +1362,4 @@ void AArch64InstPrinter::printSVERegOp(const MCInst *MI, unsigned OpNum,
|
|||
O << getRegisterName(Reg);
|
||||
if (suffix != 0)
|
||||
O << '.' << suffix;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,10 +71,9 @@ protected:
|
|||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printAddSubImm(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printLogicalImm32(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printLogicalImm64(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
template <typename T>
|
||||
void printLogicalImm(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printShifter(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printShiftedRegister(const MCInst *MI, unsigned OpNum,
|
||||
|
|
|
@ -213,7 +213,8 @@ static inline uint64_t ror(uint64_t elt, unsigned size) {
|
|||
static inline bool processLogicalImmediate(uint64_t Imm, unsigned RegSize,
|
||||
uint64_t &Encoding) {
|
||||
if (Imm == 0ULL || Imm == ~0ULL ||
|
||||
(RegSize != 64 && (Imm >> RegSize != 0 || Imm == ~0U)))
|
||||
(RegSize != 64 &&
|
||||
(Imm >> RegSize != 0 || Imm == (~0ULL >> (64 - RegSize)))))
|
||||
return false;
|
||||
|
||||
// First, determine the element size.
|
||||
|
|
Loading…
Reference in New Issue