From 40ea4329b1278e781d31647998b008779e36fad4 Mon Sep 17 00:00:00 2001 From: Bradley Smith Date: Thu, 8 May 2014 14:12:12 +0000 Subject: [PATCH] [ARM64] Ensure immediates in extend operands are in a valid range Also emit a more useful diagnostic when they are not. llvm-svn: 208318 --- lib/Target/ARM64/ARM64InstrFormats.td | 7 ++++++- lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/Target/ARM64/ARM64InstrFormats.td b/lib/Target/ARM64/ARM64InstrFormats.td index d14e0fd0c30..4ed37ead574 100644 --- a/lib/Target/ARM64/ARM64InstrFormats.td +++ b/lib/Target/ARM64/ARM64InstrFormats.td @@ -125,15 +125,20 @@ def MoveVecShifterOperand : AsmOperandClass { } // Extend operand for arithmetic encodings. -def ExtendOperand : AsmOperandClass { let Name = "Extend"; } +def ExtendOperand : AsmOperandClass { + let Name = "Extend"; + let DiagnosticType = "AddSubRegExtendLarge"; +} def ExtendOperand64 : AsmOperandClass { let SuperClasses = [ExtendOperand]; let Name = "Extend64"; + let DiagnosticType = "AddSubRegExtendSmall"; } // 'extend' that's a lsl of a 64-bit register. def ExtendOperandLSL64 : AsmOperandClass { let SuperClasses = [ExtendOperand]; let Name = "ExtendLSL64"; + let DiagnosticType = "AddSubRegExtendLarge"; } // 8-bit floating-point immediate encodings. diff --git a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp index 7a619fc88c6..44c8252f258 100644 --- a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -749,14 +749,15 @@ public: ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val); return ST == ARM64_AM::LSL; } - return Kind == k_Extend; + return Kind == k_Extend && ARM64_AM::getArithShiftValue(Shifter.Val) <= 4; } bool isExtend64() const { if (Kind != k_Extend) return false; // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class). ARM64_AM::ExtendType ET = ARM64_AM::getArithExtendType(Extend.Val); - return ET != ARM64_AM::UXTX && ET != ARM64_AM::SXTX; + return ET != ARM64_AM::UXTX && ET != ARM64_AM::SXTX && + ARM64_AM::getArithShiftValue(Shifter.Val) <= 4; } bool isExtendLSL64() const { // lsl is an alias for UXTX but will be a parsed as a k_Shifter operand. @@ -767,7 +768,8 @@ public: if (Kind != k_Extend) return false; ARM64_AM::ExtendType ET = ARM64_AM::getArithExtendType(Extend.Val); - return ET == ARM64_AM::UXTX || ET == ARM64_AM::SXTX; + return (ET == ARM64_AM::UXTX || ET == ARM64_AM::SXTX) && + ARM64_AM::getArithShiftValue(Shifter.Val) <= 4; } bool isArithmeticShifter() const { @@ -3871,6 +3873,12 @@ bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) { return Error(Loc, "invalid operand for instruction"); case Match_InvalidSuffix: return Error(Loc, "invalid type suffix for instruction"); + case Match_AddSubRegExtendSmall: + return Error(Loc, + "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]"); + case Match_AddSubRegExtendLarge: + return Error(Loc, + "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]"); case Match_InvalidMemoryIndexedSImm9: return Error(Loc, "index must be an integer in range [-256, 255]."); case Match_InvalidMemoryIndexed32SImm7: @@ -4447,6 +4455,8 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, ((ARM64Operand *)Operands[ErrorInfo + 1])->isTokenEqual("!")) MatchResult = Match_InvalidMemoryIndexedSImm9; // FALL THROUGH + case Match_AddSubRegExtendSmall: + case Match_AddSubRegExtendLarge: case Match_InvalidMemoryIndexed8: case Match_InvalidMemoryIndexed16: case Match_InvalidMemoryIndexed32SImm7: