From: Bradley Smith Date: Mon, 12 May 2014 09:41:43 +0000 (+0000) Subject: [ARM64] Correct more bounds checks/diagnostics for arithmetic shift operands X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0ce7616654c805ea51c1bedb46ae6e3433dbc320;p=oota-llvm.git [ARM64] Correct more bounds checks/diagnostics for arithmetic shift operands git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208528 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM64/ARM64InstrFormats.td b/lib/Target/ARM64/ARM64InstrFormats.td index f44f45ed3d9..4e97a99ef68 100644 --- a/lib/Target/ARM64/ARM64InstrFormats.td +++ b/lib/Target/ARM64/ARM64InstrFormats.td @@ -100,7 +100,7 @@ def MovImm64ShifterOperand : AsmOperandClass { class ArithmeticShifterOperand : 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/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp index 8276b5fc830..98e428069dc 100644 --- a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ b/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 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; } diff --git a/test/MC/ARM64/arithmetic-encoding.s b/test/MC/ARM64/arithmetic-encoding.s index 7a30e998cb0..05b874cda59 100644 --- a/test/MC/ARM64/arithmetic-encoding.s +++ b/test/MC/ARM64/arithmetic-encoding.s @@ -107,72 +107,56 @@ foo: add x12, x13, x14 add w12, w13, w14, lsl #12 add x12, x13, x14, lsl #12 - add w12, w13, w14, lsr #42 add x12, x13, x14, lsr #42 - add w12, w13, w14, asr #39 add x12, x13, x14, asr #39 ; CHECK: add w12, w13, w14 ; encoding: [0xac,0x01,0x0e,0x0b] ; CHECK: add x12, x13, x14 ; encoding: [0xac,0x01,0x0e,0x8b] ; CHECK: add w12, w13, w14, lsl #12 ; encoding: [0xac,0x31,0x0e,0x0b] ; CHECK: add x12, x13, x14, lsl #12 ; encoding: [0xac,0x31,0x0e,0x8b] -; CHECK: add w12, w13, w14, lsr #42 ; encoding: [0xac,0xa9,0x4e,0x0b] ; CHECK: add x12, x13, x14, lsr #42 ; encoding: [0xac,0xa9,0x4e,0x8b] -; CHECK: add w12, w13, w14, asr #39 ; encoding: [0xac,0x9d,0x8e,0x0b] ; CHECK: add x12, x13, x14, asr #39 ; encoding: [0xac,0x9d,0x8e,0x8b] sub w12, w13, w14 sub x12, x13, x14 sub w12, w13, w14, lsl #12 sub x12, x13, x14, lsl #12 - sub w12, w13, w14, lsr #42 sub x12, x13, x14, lsr #42 - sub w12, w13, w14, asr #39 sub x12, x13, x14, asr #39 ; CHECK: sub w12, w13, w14 ; encoding: [0xac,0x01,0x0e,0x4b] ; CHECK: sub x12, x13, x14 ; encoding: [0xac,0x01,0x0e,0xcb] ; CHECK: sub w12, w13, w14, lsl #12 ; encoding: [0xac,0x31,0x0e,0x4b] ; CHECK: sub x12, x13, x14, lsl #12 ; encoding: [0xac,0x31,0x0e,0xcb] -; CHECK: sub w12, w13, w14, lsr #42 ; encoding: [0xac,0xa9,0x4e,0x4b] ; CHECK: sub x12, x13, x14, lsr #42 ; encoding: [0xac,0xa9,0x4e,0xcb] -; CHECK: sub w12, w13, w14, asr #39 ; encoding: [0xac,0x9d,0x8e,0x4b] ; CHECK: sub x12, x13, x14, asr #39 ; encoding: [0xac,0x9d,0x8e,0xcb] adds w12, w13, w14 adds x12, x13, x14 adds w12, w13, w14, lsl #12 adds x12, x13, x14, lsl #12 - adds w12, w13, w14, lsr #42 adds x12, x13, x14, lsr #42 - adds w12, w13, w14, asr #39 adds x12, x13, x14, asr #39 ; CHECK: adds w12, w13, w14 ; encoding: [0xac,0x01,0x0e,0x2b] ; CHECK: adds x12, x13, x14 ; encoding: [0xac,0x01,0x0e,0xab] ; CHECK: adds w12, w13, w14, lsl #12 ; encoding: [0xac,0x31,0x0e,0x2b] ; CHECK: adds x12, x13, x14, lsl #12 ; encoding: [0xac,0x31,0x0e,0xab] -; CHECK: adds w12, w13, w14, lsr #42 ; encoding: [0xac,0xa9,0x4e,0x2b] ; CHECK: adds x12, x13, x14, lsr #42 ; encoding: [0xac,0xa9,0x4e,0xab] -; CHECK: adds w12, w13, w14, asr #39 ; encoding: [0xac,0x9d,0x8e,0x2b] ; CHECK: adds x12, x13, x14, asr #39 ; encoding: [0xac,0x9d,0x8e,0xab] subs w12, w13, w14 subs x12, x13, x14 subs w12, w13, w14, lsl #12 subs x12, x13, x14, lsl #12 - subs w12, w13, w14, lsr #42 subs x12, x13, x14, lsr #42 - subs w12, w13, w14, asr #39 subs x12, x13, x14, asr #39 ; CHECK: subs w12, w13, w14 ; encoding: [0xac,0x01,0x0e,0x6b] ; CHECK: subs x12, x13, x14 ; encoding: [0xac,0x01,0x0e,0xeb] ; CHECK: subs w12, w13, w14, lsl #12 ; encoding: [0xac,0x31,0x0e,0x6b] ; CHECK: subs x12, x13, x14, lsl #12 ; encoding: [0xac,0x31,0x0e,0xeb] -; CHECK: subs w12, w13, w14, lsr #42 ; encoding: [0xac,0xa9,0x4e,0x6b] ; CHECK: subs x12, x13, x14, lsr #42 ; encoding: [0xac,0xa9,0x4e,0xeb] -; CHECK: subs w12, w13, w14, asr #39 ; encoding: [0xac,0x9d,0x8e,0x6b] ; CHECK: subs x12, x13, x14, asr #39 ; encoding: [0xac,0x9d,0x8e,0xeb] ; Check use of upper case register names rdar://14354073 diff --git a/test/MC/ARM64/diags.s b/test/MC/ARM64/diags.s index 7d9ed5f2043..9846450b208 100644 --- a/test/MC/ARM64/diags.s +++ b/test/MC/ARM64/diags.s @@ -176,7 +176,7 @@ foo: ; Where the immediate is out of range. add w1, w2, w3, lsr #75 -; CHECK-ERRORS: error: immediate value too large for shifter operand +; CHECK-ERRORS: error: expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4] ; CHECK-ERRORS: add w1, w2, w3, lsr #75 ; CHECK-ERRORS: ^