summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp35
-rw-r--r--llvm/test/MC/AArch64/basic-a64-diagnostics.s14
2 files changed, 27 insertions, 22 deletions
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index cbab68979c5..347cffe72c3 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -2100,27 +2100,9 @@ AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
bool isNegative = parseOptionalToken(AsmToken::Minus);
const AsmToken &Tok = Parser.getTok();
- if (Tok.is(AsmToken::Real)) {
- APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
- if (isNegative)
- RealVal.changeSign();
-
- uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
- int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
- Parser.Lex(); // Eat the token.
- // Check for out of range values. As an exception, we let Zero through,
- // as we handle that special case in post-processing before matching in
- // order to use the zero register for it.
- if (Val == -1 && !RealVal.isPosZero()) {
- TokError("expected compatible register or floating-point constant");
- return MatchOperand_ParseFail;
- }
- Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
- return MatchOperand_Success;
- }
- if (Tok.is(AsmToken::Integer)) {
+ if (Tok.is(AsmToken::Real) || Tok.is(AsmToken::Integer)) {
int64_t Val;
- if (!isNegative && Tok.getString().startswith("0x")) {
+ if (Tok.is(AsmToken::Integer) && !isNegative && Tok.getString().startswith("0x")) {
Val = Tok.getIntVal();
if (Val > 255 || Val < 0) {
TokError("encoded floating point value out of range");
@@ -2128,10 +2110,19 @@ AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
}
} else {
APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
+ if (isNegative)
+ RealVal.changeSign();
+
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
- // If we had a '-' in front, toggle the sign bit.
- IntVal ^= (uint64_t)isNegative << 63;
Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
+
+ // Check for out of range values. As an exception, we let Zero through,
+ // as we handle that special case in post-processing before matching in
+ // order to use the zero register for it.
+ if (Val == -1 && !RealVal.isPosZero()) {
+ TokError("expected compatible register or floating-point constant");
+ return MatchOperand_ParseFail;
+ }
}
Parser.Lex(); // Eat the token.
Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
diff --git a/llvm/test/MC/AArch64/basic-a64-diagnostics.s b/llvm/test/MC/AArch64/basic-a64-diagnostics.s
index 80e32c48673..ca513327400 100644
--- a/llvm/test/MC/AArch64/basic-a64-diagnostics.s
+++ b/llvm/test/MC/AArch64/basic-a64-diagnostics.s
@@ -1781,12 +1781,20 @@
;; Exponent too large
fmov d3, #0.0625
fmov s2, #32.0
+ fmov s2, #32
+ fmov v0.4s, #-32
// CHECK-ERROR: error: expected compatible register or floating-point constant
// CHECK-ERROR-NEXT: fmov d3, #0.0625
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
// CHECK-ERROR-NEXT: fmov s2, #32.0
// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
+// CHECK-ERROR-NEXT: fmov s2, #32
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
+// CHECK-ERROR-NEXT: fmov v0.4s, #-32
+// CHECK-ERROR-NEXT: ^
;; Fraction too precise
fmov s9, #1.03125
@@ -1798,6 +1806,12 @@
// CHECK-ERROR-NEXT: fmov s28, #1.96875
// CHECK-ERROR-NEXT: ^
+ ;; Explicitly encoded value too large
+ fmov s15, #0x100
+// CHECK-ERROR: error: encoded floating point value out of range
+// CHECK-ERROR-NEXT: fmov s15, #0x100
+// CHECK-ERROR-NEXT: ^
+
;; No particular reason, but a striking omission
fmov d0, #0.0
// CHECK-ERROR-AARCH64: error: expected compatible register or floating-point constant
OpenPOWER on IntegriCloud