1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

[ARM64] Ensure immediates in extend operands are in a valid range

Also emit a more useful diagnostic when they are not.

llvm-svn: 208318
This commit is contained in:
Bradley Smith 2014-05-08 14:12:12 +00:00
parent 0bcfb4a0bc
commit 40ea4329b1
2 changed files with 19 additions and 4 deletions

View File

@ -125,15 +125,20 @@ def MoveVecShifterOperand : AsmOperandClass {
} }
// Extend operand for arithmetic encodings. // Extend operand for arithmetic encodings.
def ExtendOperand : AsmOperandClass { let Name = "Extend"; } def ExtendOperand : AsmOperandClass {
let Name = "Extend";
let DiagnosticType = "AddSubRegExtendLarge";
}
def ExtendOperand64 : AsmOperandClass { def ExtendOperand64 : AsmOperandClass {
let SuperClasses = [ExtendOperand]; let SuperClasses = [ExtendOperand];
let Name = "Extend64"; let Name = "Extend64";
let DiagnosticType = "AddSubRegExtendSmall";
} }
// 'extend' that's a lsl of a 64-bit register. // 'extend' that's a lsl of a 64-bit register.
def ExtendOperandLSL64 : AsmOperandClass { def ExtendOperandLSL64 : AsmOperandClass {
let SuperClasses = [ExtendOperand]; let SuperClasses = [ExtendOperand];
let Name = "ExtendLSL64"; let Name = "ExtendLSL64";
let DiagnosticType = "AddSubRegExtendLarge";
} }
// 8-bit floating-point immediate encodings. // 8-bit floating-point immediate encodings.

View File

@ -749,14 +749,15 @@ public:
ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val); ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
return ST == ARM64_AM::LSL; return ST == ARM64_AM::LSL;
} }
return Kind == k_Extend; return Kind == k_Extend && ARM64_AM::getArithShiftValue(Shifter.Val) <= 4;
} }
bool isExtend64() const { bool isExtend64() const {
if (Kind != k_Extend) if (Kind != k_Extend)
return false; return false;
// UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class). // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class).
ARM64_AM::ExtendType ET = ARM64_AM::getArithExtendType(Extend.Val); 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 { bool isExtendLSL64() const {
// lsl is an alias for UXTX but will be a parsed as a k_Shifter operand. // 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) if (Kind != k_Extend)
return false; return false;
ARM64_AM::ExtendType ET = ARM64_AM::getArithExtendType(Extend.Val); 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 { bool isArithmeticShifter() const {
@ -3871,6 +3873,12 @@ bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
return Error(Loc, "invalid operand for instruction"); return Error(Loc, "invalid operand for instruction");
case Match_InvalidSuffix: case Match_InvalidSuffix:
return Error(Loc, "invalid type suffix for instruction"); 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: case Match_InvalidMemoryIndexedSImm9:
return Error(Loc, "index must be an integer in range [-256, 255]."); return Error(Loc, "index must be an integer in range [-256, 255].");
case Match_InvalidMemoryIndexed32SImm7: case Match_InvalidMemoryIndexed32SImm7:
@ -4447,6 +4455,8 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
((ARM64Operand *)Operands[ErrorInfo + 1])->isTokenEqual("!")) ((ARM64Operand *)Operands[ErrorInfo + 1])->isTokenEqual("!"))
MatchResult = Match_InvalidMemoryIndexedSImm9; MatchResult = Match_InvalidMemoryIndexedSImm9;
// FALL THROUGH // FALL THROUGH
case Match_AddSubRegExtendSmall:
case Match_AddSubRegExtendLarge:
case Match_InvalidMemoryIndexed8: case Match_InvalidMemoryIndexed8:
case Match_InvalidMemoryIndexed16: case Match_InvalidMemoryIndexed16:
case Match_InvalidMemoryIndexed32SImm7: case Match_InvalidMemoryIndexed32SImm7: