From a1c259c22cb4bf0077461398fcd029769b3d86f0 Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Mon, 29 Jan 2018 13:05:38 +0000 Subject: [PATCH] [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 --- .../lib/Target/AArch64/AArch64InstrFormats.td | 12 +++- .../AArch64/AsmParser/AArch64AsmParser.cpp | 69 +++++-------------- .../InstPrinter/AArch64InstPrinter.cpp | 19 ++--- .../AArch64/InstPrinter/AArch64InstPrinter.h | 7 +- .../MCTargetDesc/AArch64AddressingModes.h | 3 +- 5 files changed, 38 insertions(+), 72 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 0efbc3a6719f..9a32ac3dda9a 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -501,27 +501,35 @@ def logical_imm64_XFORM : SDNodeXForm, IntImmLeaf { - let PrintMethod = "printLogicalImm32"; + let PrintMethod = "printLogicalImm"; let ParserMatchClass = LogicalImm32Operand; } def logical_imm64 : Operand, IntImmLeaf { - let PrintMethod = "printLogicalImm64"; + let PrintMethod = "printLogicalImm"; let ParserMatchClass = LogicalImm64Operand; } def logical_imm32_not : Operand { diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 34e1fce72438..a04754bdda38 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -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 + bool isLogicalImm() const { if (!isImm()) return false; const MCConstantExpr *MCE = dyn_cast(getImm()); if (!MCE) return false; + int64_t Val = MCE->getValue(); - if (Val >> 32 != 0 && Val >> 32 != ~0LL) + int64_t SVal = typename std::make_signed::type(Val); + int64_t UVal = typename std::make_unsigned::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(getImm()); - if (!MCE) - return false; - return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64); - } - - bool isLogicalImm32Not() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(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(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 + void addLogicalImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); const MCConstantExpr *MCE = cast(getImm()); - uint64_t encoding = - AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32); + typename std::make_unsigned::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 + void addLogicalImmNotOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); const MCConstantExpr *MCE = cast(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(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(getImm()); - uint64_t encoding = - AArch64_AM::encodeLogicalImmediate(~MCE->getValue(), 64); + typename std::make_unsigned::type Val = ~MCE->getValue(); + uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8); Inst.addOperand(MCOperand::createImm(encoding)); } diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp index 119de4c08d3a..a34864cdad7c 100644 --- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -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 +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; -} \ No newline at end of file +} diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h index baf11e5c9c61..de127ac22d82 100644 --- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -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 + 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, diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h index 3e5ef4df4706..fdd9c960dab6 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h @@ -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.