[llvm] r208540 - [ARM64] Add proper bounds checking/diagnostics to logical shifts
Bradley Smith
bradley.smith at arm.com
Mon May 12 04:49:17 PDT 2014
Author: brasmi01
Date: Mon May 12 06:49:16 2014
New Revision: 208540
URL: http://llvm.org/viewvc/llvm-project?rev=208540&view=rev
Log:
[ARM64] Add proper bounds checking/diagnostics to logical shifts
Modified:
llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td
llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
llvm/trunk/test/MC/ARM64/diags.s
Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td?rev=208540&r1=208539&r2=208540&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td Mon May 12 06:49:16 2014
@@ -108,6 +108,18 @@ class ArithmeticShifterOperand<int width
def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
+// Shifter operand for logical register shifted encodings.
+class LogicalShifterOperand<int width> : AsmOperandClass {
+ let SuperClasses = [ShifterOperand];
+ let Name = "LogicalShifter" # width;
+ let PredicateMethod = "isLogicalShifter<" # width # ">";
+ let RenderMethod = "addLogicalShifterOperands";
+ let DiagnosticType = "AddSubRegShift" # width;
+}
+
+def LogicalShifterOperand32 : LogicalShifterOperand<32>;
+def LogicalShifterOperand64 : LogicalShifterOperand<64>;
+
// Shifter operand for logical vector 128/64-bit shifted encodings.
def LogicalVecShifterOperand : AsmOperandClass {
let SuperClasses = [ShifterOperand];
@@ -525,20 +537,24 @@ def arith_shifted_reg64 : arith_shifted_
// An arithmetic shifter operand:
// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
// {5-0} - imm6
-def logical_shift : Operand<i32> {
+class logical_shift<int width> : Operand<i32> {
let PrintMethod = "printShifter";
- let ParserMatchClass = ShifterOperand;
+ let ParserMatchClass = !cast<AsmOperandClass>(
+ "LogicalShifterOperand" # width);
}
-class logical_shifted_reg<ValueType Ty, RegisterClass regclass>
+def logical_shift32 : logical_shift<32>;
+def logical_shift64 : logical_shift<64>;
+
+class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
: Operand<Ty>,
ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
let PrintMethod = "printShiftedRegister";
- let MIOperandInfo = (ops regclass, logical_shift);
+ let MIOperandInfo = (ops regclass, shiftop);
}
-def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32>;
-def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64>;
+def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
+def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
// A logical vector shifter operand:
// {7-6} - shift type: 00 = lsl
Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td?rev=208540&r1=208539&r2=208540&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td Mon May 12 06:49:16 2014
@@ -671,9 +671,9 @@ def : InstAlias<"tst $src1, $src2",
(ANDSXrs XZR, GPR64:$src1, GPR64:$src2, 0)>;
def : InstAlias<"tst $src1, $src2, $sh",
- (ANDSWrs WZR, GPR32:$src1, GPR32:$src2, logical_shift:$sh)>;
+ (ANDSWrs WZR, GPR32:$src1, GPR32:$src2, logical_shift32:$sh)>;
def : InstAlias<"tst $src1, $src2, $sh",
- (ANDSXrs XZR, GPR64:$src1, GPR64:$src2, logical_shift:$sh)>;
+ (ANDSXrs XZR, GPR64:$src1, GPR64:$src2, logical_shift64:$sh)>;
def : InstAlias<"mvn $Wd, $Wm",
(ORNWrs GPR32:$Wd, WZR, GPR32:$Wm, 0)>;
@@ -681,9 +681,9 @@ def : InstAlias<"mvn $Xd, $Xm",
(ORNXrs GPR64:$Xd, XZR, GPR64:$Xm, 0)>;
def : InstAlias<"mvn $Wd, $Wm, $sh",
- (ORNWrs GPR32:$Wd, WZR, GPR32:$Wm, logical_shift:$sh)>;
+ (ORNWrs GPR32:$Wd, WZR, GPR32:$Wm, logical_shift32:$sh)>;
def : InstAlias<"mvn $Xd, $Xm, $sh",
- (ORNXrs GPR64:$Xd, XZR, GPR64:$Xm, logical_shift:$sh)>;
+ (ORNXrs GPR64:$Xd, XZR, GPR64:$Xm, logical_shift64:$sh)>;
def : Pat<(not GPR32:$Wm), (ORNWrr WZR, GPR32:$Wm)>;
def : Pat<(not GPR64:$Xm), (ORNXrr XZR, GPR64:$Xm)>;
Modified: llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp?rev=208540&r1=208539&r2=208540&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp Mon May 12 06:49:16 2014
@@ -845,6 +845,18 @@ public:
ST == ARM64_AM::ASR) && ARM64_AM::getShiftValue(Shifter.Val) < width;
}
+ template <unsigned width>
+ bool isLogicalShifter() const {
+ if (!isShifter())
+ return false;
+
+ // A logical shifter is LSL, LSR, ASR or ROR.
+ ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
+ return (ST == ARM64_AM::LSL || ST == ARM64_AM::LSR ||
+ ST == ARM64_AM::ASR || ST == ARM64_AM::ROR) &&
+ ARM64_AM::getShiftValue(Shifter.Val) < width;
+ }
+
bool isMovImm32Shifter() const {
if (!isShifter())
return false;
@@ -1453,6 +1465,11 @@ public:
Inst.addOperand(MCOperand::CreateImm(getShifter()));
}
+ void addLogicalShifterOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateImm(getShifter()));
+ }
+
void addMovImm32ShifterOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateImm(getShifter()));
@@ -3677,18 +3694,6 @@ bool ARM64AsmParser::validateInstruction
// in the instructions being checked and this keeps the nested conditionals
// to a minimum.
switch (Inst.getOpcode()) {
- case ARM64::ANDWrs:
- case ARM64::ANDSWrs:
- case ARM64::EORWrs:
- case ARM64::ORRWrs: {
- if (!Inst.getOperand(3).isImm())
- return Error(Loc[3], "immediate value expected");
- int64_t shifter = Inst.getOperand(3).getImm();
- ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(shifter);
- if (ST == ARM64_AM::LSL && shifter > 31)
- return Error(Loc[3], "shift value out of range");
- return false;
- }
case ARM64::ADDSWri:
case ARM64::ADDSXri:
case ARM64::ADDWri:
Modified: llvm/trunk/test/MC/ARM64/diags.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/diags.s?rev=208540&r1=208539&r2=208540&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/diags.s (original)
+++ llvm/trunk/test/MC/ARM64/diags.s Mon May 12 06:49:16 2014
@@ -182,19 +182,19 @@ foo:
; logical instructions on 32-bit regs with shift > 31 is not legal
orr w0, w0, w0, lsl #32
-; CHECK-ERRORS: error: shift value out of range
+; CHECK-ERRORS: error: expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]
; CHECK-ERRORS: orr w0, w0, w0, lsl #32
; CHECK-ERRORS: ^
eor w0, w0, w0, lsl #32
-; CHECK-ERRORS: error: shift value out of range
+; CHECK-ERRORS: error: expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]
; CHECK-ERRORS: eor w0, w0, w0, lsl #32
; CHECK-ERRORS: ^
and w0, w0, w0, lsl #32
-; CHECK-ERRORS: error: shift value out of range
+; CHECK-ERRORS: error: expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]
; CHECK-ERRORS: and w0, w0, w0, lsl #32
; CHECK-ERRORS: ^
ands w0, w0, w0, lsl #32
-; CHECK-ERRORS: error: shift value out of range
+; CHECK-ERRORS: error: expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]
; CHECK-ERRORS: ands w0, w0, w0, lsl #32
; CHECK-ERRORS: ^
More information about the llvm-commits
mailing list