summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorBradley Smith <bradley.smith@arm.com>2014-05-12 09:41:43 +0000
committerBradley Smith <bradley.smith@arm.com>2014-05-12 09:41:43 +0000
commit9ba3c963ff7fe62b26332e3097b406eb617dae51 (patch)
treefa0d03bae4ff5d8a61638a067a186fad3d75ce2a /llvm/lib
parentad363d712153bdacc1713e1661487a88bfd02d65 (diff)
downloadbcm5719-llvm-9ba3c963ff7fe62b26332e3097b406eb617dae51.tar.gz
bcm5719-llvm-9ba3c963ff7fe62b26332e3097b406eb617dae51.zip
[ARM64] Correct more bounds checks/diagnostics for arithmetic shift operands
llvm-svn: 208528
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM64/ARM64InstrFormats.td2
-rw-r--r--llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp26
2 files changed, 18 insertions, 10 deletions
diff --git a/llvm/lib/Target/ARM64/ARM64InstrFormats.td b/llvm/lib/Target/ARM64/ARM64InstrFormats.td
index f44f45ed3d9..4e97a99ef68 100644
--- a/llvm/lib/Target/ARM64/ARM64InstrFormats.td
+++ b/llvm/lib/Target/ARM64/ARM64InstrFormats.td
@@ -100,7 +100,7 @@ def MovImm64ShifterOperand : AsmOperandClass {
class ArithmeticShifterOperand<int width> : AsmOperandClass {
let SuperClasses = [ShifterOperand];
let Name = "ArithmeticShifter" # width;
- let PredicateMethod = "isArithmeticShifter";
+ let PredicateMethod = "isArithmeticShifter<" # width # ">";
let RenderMethod = "addArithmeticShifterOperands";
let DiagnosticType = "AddSubRegShift" # width;
}
diff --git a/llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp b/llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
index 8276b5fc830..98e428069dc 100644
--- a/llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
+++ b/llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
@@ -807,7 +807,8 @@ public:
// lsl is an alias for UXTW but will be a parsed as a k_Shifter operand.
if (isShifter()) {
ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
- return ST == ARM64_AM::LSL;
+ return ST == ARM64_AM::LSL &&
+ ARM64_AM::getShiftValue(Shifter.Val) <= 4;
}
return Kind == k_Extend && ARM64_AM::getArithShiftValue(Shifter.Val) <= 4;
}
@@ -823,7 +824,8 @@ public:
// lsl is an alias for UXTX but will be a parsed as a k_Shifter operand.
if (isShifter()) {
ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
- return ST == ARM64_AM::LSL;
+ return ST == ARM64_AM::LSL &&
+ ARM64_AM::getShiftValue(Shifter.Val) <= 4;
}
if (Kind != k_Extend)
return false;
@@ -832,13 +834,15 @@ public:
ARM64_AM::getArithShiftValue(Shifter.Val) <= 4;
}
+ template <unsigned width>
bool isArithmeticShifter() const {
if (!isShifter())
return false;
// An arithmetic shifter is LSL, LSR, or ASR.
ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
- return ST == ARM64_AM::LSL || ST == ARM64_AM::LSR || ST == ARM64_AM::ASR;
+ return (ST == ARM64_AM::LSL || ST == ARM64_AM::LSR ||
+ ST == ARM64_AM::ASR) && ARM64_AM::getShiftValue(Shifter.Val) < width;
}
bool isMovImm32Shifter() const {
@@ -2454,7 +2458,6 @@ ARM64AsmParser::tryParseOptionalShift(OperandVector &Operands) {
return MatchOperand_ParseFail;
}
- SMLoc ExprLoc = getLoc();
const MCExpr *ImmVal;
if (getParser().parseExpression(ImmVal))
return MatchOperand_ParseFail;
@@ -2465,14 +2468,19 @@ ARM64AsmParser::tryParseOptionalShift(OperandVector &Operands) {
return MatchOperand_ParseFail;
}
+ SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
+
+ // If we have an shift that is too large to encode then crudely pass it
+ // through as an invalid shift that is encodable so that we get consistant
+ // diagnostics rather than ones different from out of range 32-bit shifts.
if ((MCE->getValue() & 0x3f) != MCE->getValue()) {
- Error(ExprLoc, "immediate value too large for shifter operand");
- return MatchOperand_ParseFail;
+ Operands.push_back(ARM64Operand::CreateShifter(ARM64_AM::InvalidShift, 0, S,
+ E, getContext()));
+ } else {
+ Operands.push_back(ARM64Operand::CreateShifter(ShOp, MCE->getValue(), S,
+ E, getContext()));
}
- SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
- Operands.push_back(
- ARM64Operand::CreateShifter(ShOp, MCE->getValue(), S, E, getContext()));
return MatchOperand_Success;
}
OpenPOWER on IntegriCloud