Index: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td @@ -501,27 +501,35 @@ let DiagnosticType = "LogicalSecondSource" in { def LogicalImm32Operand : AsmOperandClass { let Name = "LogicalImm32"; + let PredicateMethod = "isLogicalImm"; + let RenderMethod = "addLogicalImmOperands"; } def LogicalImm64Operand : AsmOperandClass { let Name = "LogicalImm64"; + let PredicateMethod = "isLogicalImm"; + let RenderMethod = "addLogicalImmOperands"; } def LogicalImm32NotOperand : AsmOperandClass { let Name = "LogicalImm32Not"; + let PredicateMethod = "isLogicalImm"; + let RenderMethod = "addLogicalImmNotOperands"; } def LogicalImm64NotOperand : AsmOperandClass { let Name = "LogicalImm64Not"; + let PredicateMethod = "isLogicalImm"; + let RenderMethod = "addLogicalImmNotOperands"; } } def logical_imm32 : Operand, 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 { Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -555,45 +555,23 @@ 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) - 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) + int64_t Val = MCE->getValue(); + 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; - 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 @@ Inst.addOperand(MCOperand::createImm(MCE->getValue())); } - void addLogicalImm32Operands(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); - Inst.addOperand(MCOperand::createImm(encoding)); - } - - void addLogicalImm64Operands(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 { + template + void addLogicalImmOperands(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); + typename std::make_unsigned::type Val = MCE->getValue(); + uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8); Inst.addOperand(MCOperand::createImm(encoding)); } - void addLogicalImm64NotOperands(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); + typename std::make_unsigned::type Val = ~MCE->getValue(); + uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8); Inst.addOperand(MCOperand::createImm(encoding)); } Index: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h =================================================================== --- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -71,10 +71,9 @@ 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, Index: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -907,20 +907,13 @@ } } -void AArch64InstPrinter::printLogicalImm32(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) { +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, 64)); + O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 8 * sizeof(T))); } void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum, @@ -1369,4 +1362,4 @@ O << getRegisterName(Reg); if (suffix != 0) O << '.' << suffix; -} \ No newline at end of file +} Index: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h =================================================================== --- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h +++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h @@ -213,7 +213,8 @@ 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.