[ARM64] Ensure immediates in extend operands are in a valid range
authorBradley Smith <bradley.smith@arm.com>
Thu, 8 May 2014 14:12:12 +0000 (14:12 +0000)
committerBradley Smith <bradley.smith@arm.com>
Thu, 8 May 2014 14:12:12 +0000 (14:12 +0000)
Also emit a more useful diagnostic when they are not.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208318 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM64/ARM64InstrFormats.td
lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp

index d14e0fd0c30f7146b408dc2b7d8a47a0a2780fb8..4ed37ead5746f866095e1e6fc98d15230593c8f8 100644 (file)
@@ -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.
index 7a619fc88c60fa1aa305acbdf2fb7dec48a4b563..44c8252f2587e2b9dbf6199330606b4a7b2b47f7 100644 (file)
@@ -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: