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 {
|
let DiagnosticType = "LogicalSecondSource" in {
|
||||||
def LogicalImm32Operand : AsmOperandClass {
|
def LogicalImm32Operand : AsmOperandClass {
|
||||||
let Name = "LogicalImm32";
|
let Name = "LogicalImm32";
|
||||||
|
let PredicateMethod = "isLogicalImm<int32_t>";
|
||||||
|
let RenderMethod = "addLogicalImmOperands<int32_t>";
|
||||||
}
|
}
|
||||||
def LogicalImm64Operand : AsmOperandClass {
|
def LogicalImm64Operand : AsmOperandClass {
|
||||||
let Name = "LogicalImm64";
|
let Name = "LogicalImm64";
|
||||||
|
let PredicateMethod = "isLogicalImm<int64_t>";
|
||||||
|
let RenderMethod = "addLogicalImmOperands<int64_t>";
|
||||||
}
|
}
|
||||||
def LogicalImm32NotOperand : AsmOperandClass {
|
def LogicalImm32NotOperand : AsmOperandClass {
|
||||||
let Name = "LogicalImm32Not";
|
let Name = "LogicalImm32Not";
|
||||||
|
let PredicateMethod = "isLogicalImm<int32_t>";
|
||||||
|
let RenderMethod = "addLogicalImmNotOperands<int32_t>";
|
||||||
}
|
}
|
||||||
def LogicalImm64NotOperand : AsmOperandClass {
|
def LogicalImm64NotOperand : AsmOperandClass {
|
||||||
let Name = "LogicalImm64Not";
|
let Name = "LogicalImm64Not";
|
||||||
|
let PredicateMethod = "isLogicalImm<int64_t>";
|
||||||
|
let RenderMethod = "addLogicalImmNotOperands<int64_t>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
|
def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
|
||||||
return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
|
return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
|
||||||
}], logical_imm32_XFORM> {
|
}], logical_imm32_XFORM> {
|
||||||
let PrintMethod = "printLogicalImm32";
|
let PrintMethod = "printLogicalImm<int32_t>";
|
||||||
let ParserMatchClass = LogicalImm32Operand;
|
let ParserMatchClass = LogicalImm32Operand;
|
||||||
}
|
}
|
||||||
def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
|
def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
|
||||||
return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
|
return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
|
||||||
}], logical_imm64_XFORM> {
|
}], logical_imm64_XFORM> {
|
||||||
let PrintMethod = "printLogicalImm64";
|
let PrintMethod = "printLogicalImm<int64_t>";
|
||||||
let ParserMatchClass = LogicalImm64Operand;
|
let ParserMatchClass = LogicalImm64Operand;
|
||||||
}
|
}
|
||||||
def logical_imm32_not : Operand<i32> {
|
def logical_imm32_not : Operand<i32> {
|
||||||
|
|
|
@ -555,45 +555,23 @@ public:
|
||||||
return (Val >= N && Val <= M);
|
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())
|
if (!isImm())
|
||||||
return false;
|
return false;
|
||||||
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
|
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
|
||||||
if (!MCE)
|
if (!MCE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int64_t Val = MCE->getValue();
|
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;
|
return false;
|
||||||
Val &= 0xFFFFFFFF;
|
|
||||||
return AArch64_AM::isLogicalImmediate(Val, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLogicalImm64() const {
|
return AArch64_AM::isLogicalImmediate(UVal, sizeof(T) * 8);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isShiftedImm() const { return Kind == k_ShiftedImm; }
|
bool isShiftedImm() const { return Kind == k_ShiftedImm; }
|
||||||
|
@ -1378,34 +1356,21 @@ public:
|
||||||
Inst.addOperand(MCOperand::createImm(MCE->getValue()));
|
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!");
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
|
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
|
||||||
uint64_t encoding =
|
typename std::make_unsigned<T>::type Val = MCE->getValue();
|
||||||
AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32);
|
uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8);
|
||||||
Inst.addOperand(MCOperand::createImm(encoding));
|
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!");
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
|
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
|
||||||
uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
|
typename std::make_unsigned<T>::type Val = ~MCE->getValue();
|
||||||
Inst.addOperand(MCOperand::createImm(encoding));
|
uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
Inst.addOperand(MCOperand::createImm(encoding));
|
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,
|
template <typename T>
|
||||||
const MCSubtargetInfo &STI,
|
void AArch64InstPrinter::printLogicalImm(const MCInst *MI, unsigned OpNum,
|
||||||
raw_ostream &O) {
|
const MCSubtargetInfo &STI,
|
||||||
|
raw_ostream &O) {
|
||||||
uint64_t Val = MI->getOperand(OpNum).getImm();
|
uint64_t Val = MI->getOperand(OpNum).getImm();
|
||||||
O << "#0x";
|
O << "#0x";
|
||||||
O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 32));
|
O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 8 * sizeof(T)));
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum,
|
void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum,
|
||||||
|
@ -1369,4 +1362,4 @@ void AArch64InstPrinter::printSVERegOp(const MCInst *MI, unsigned OpNum,
|
||||||
O << getRegisterName(Reg);
|
O << getRegisterName(Reg);
|
||||||
if (suffix != 0)
|
if (suffix != 0)
|
||||||
O << '.' << suffix;
|
O << '.' << suffix;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,10 +71,9 @@ protected:
|
||||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||||
void printAddSubImm(const MCInst *MI, unsigned OpNum,
|
void printAddSubImm(const MCInst *MI, unsigned OpNum,
|
||||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||||
void printLogicalImm32(const MCInst *MI, unsigned OpNum,
|
template <typename T>
|
||||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
void printLogicalImm(const MCInst *MI, unsigned OpNum,
|
||||||
void printLogicalImm64(const MCInst *MI, unsigned OpNum,
|
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
|
||||||
void printShifter(const MCInst *MI, unsigned OpNum,
|
void printShifter(const MCInst *MI, unsigned OpNum,
|
||||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||||
void printShiftedRegister(const MCInst *MI, unsigned OpNum,
|
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,
|
static inline bool processLogicalImmediate(uint64_t Imm, unsigned RegSize,
|
||||||
uint64_t &Encoding) {
|
uint64_t &Encoding) {
|
||||||
if (Imm == 0ULL || Imm == ~0ULL ||
|
if (Imm == 0ULL || Imm == ~0ULL ||
|
||||||
(RegSize != 64 && (Imm >> RegSize != 0 || Imm == ~0U)))
|
(RegSize != 64 &&
|
||||||
|
(Imm >> RegSize != 0 || Imm == (~0ULL >> (64 - RegSize)))))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// First, determine the element size.
|
// First, determine the element size.
|
||||||
|
|
Loading…
Reference in New Issue