[llvm] r208529 - [ARM64] Add diagnostics for bitfield extract/insert instructions
Bradley Smith
bradley.smith at arm.com
Mon May 12 02:44:58 PDT 2014
Author: brasmi01
Date: Mon May 12 04:44:57 2014
New Revision: 208529
URL: http://llvm.org/viewvc/llvm-project?rev=208529&view=rev
Log:
[ARM64] Add diagnostics for bitfield extract/insert instructions
Unfortunately, since ARM64 models all these instructions as aliases,
the checks need to be done at the time the alias is seen rather than
during instruction validation as AArch64 does it.
Modified:
llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
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=208529&r1=208528&r2=208529&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp Mon May 12 04:44:57 2014
@@ -4181,6 +4181,20 @@ bool ARM64AsmParser::MatchAndEmitInstruc
uint64_t Op3Val = Op3CE->getValue();
uint64_t Op4Val = Op4CE->getValue();
+ uint64_t RegWidth = 0;
+ if (ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains(
+ Op1->getReg()))
+ RegWidth = 64;
+ else
+ RegWidth = 32;
+
+ if (Op3Val >= RegWidth)
+ return Error(Op3->getStartLoc(),
+ "expected integer in range [0, 31]");
+ if (Op4Val < 1 || Op4Val > RegWidth)
+ return Error(Op4->getStartLoc(),
+ "expected integer in range [1, 32]");
+
uint64_t NewOp3Val = 0;
if (ARM64MCRegisterClasses[ARM64::GPR32allRegClassID].contains(
Op1->getReg()))
@@ -4190,6 +4204,10 @@ bool ARM64AsmParser::MatchAndEmitInstruc
uint64_t NewOp4Val = Op4Val - 1;
+ if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
+ return Error(Op4->getStartLoc(),
+ "requested insert overflows register");
+
const MCExpr *NewOp3 =
MCConstantExpr::Create(NewOp3Val, getContext());
const MCExpr *NewOp4 =
@@ -4231,28 +4249,45 @@ bool ARM64AsmParser::MatchAndEmitInstruc
if (Op3CE && Op4CE) {
uint64_t Op3Val = Op3CE->getValue();
uint64_t Op4Val = Op4CE->getValue();
+
+ uint64_t RegWidth = 0;
+ if (ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains(
+ Op1->getReg()))
+ RegWidth = 64;
+ else
+ RegWidth = 32;
+
+ if (Op3Val >= RegWidth)
+ return Error(Op3->getStartLoc(),
+ "expected integer in range [0, 31]");
+ if (Op4Val < 1 || Op4Val > RegWidth)
+ return Error(Op4->getStartLoc(),
+ "expected integer in range [1, 32]");
+
uint64_t NewOp4Val = Op3Val + Op4Val - 1;
- if (NewOp4Val >= Op3Val) {
- const MCExpr *NewOp4 =
- MCConstantExpr::Create(NewOp4Val, getContext());
- Operands[4] = ARM64Operand::CreateImm(
- NewOp4, Op4->getStartLoc(), Op4->getEndLoc(), getContext());
- if (Tok == "bfxil")
- Operands[0] = ARM64Operand::CreateToken(
- "bfm", false, Op->getStartLoc(), getContext());
- else if (Tok == "sbfx")
- Operands[0] = ARM64Operand::CreateToken(
- "sbfm", false, Op->getStartLoc(), getContext());
- else if (Tok == "ubfx")
- Operands[0] = ARM64Operand::CreateToken(
- "ubfm", false, Op->getStartLoc(), getContext());
- else
- llvm_unreachable("No valid mnemonic for alias?");
-
- delete Op;
- delete Op4;
- }
+ if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
+ return Error(Op4->getStartLoc(),
+ "requested extract overflows register");
+
+ const MCExpr *NewOp4 =
+ MCConstantExpr::Create(NewOp4Val, getContext());
+ Operands[4] = ARM64Operand::CreateImm(
+ NewOp4, Op4->getStartLoc(), Op4->getEndLoc(), getContext());
+ if (Tok == "bfxil")
+ Operands[0] = ARM64Operand::CreateToken(
+ "bfm", false, Op->getStartLoc(), getContext());
+ else if (Tok == "sbfx")
+ Operands[0] = ARM64Operand::CreateToken(
+ "sbfm", false, Op->getStartLoc(), getContext());
+ else if (Tok == "ubfx")
+ Operands[0] = ARM64Operand::CreateToken(
+ "ubfm", false, Op->getStartLoc(), getContext());
+ else
+ llvm_unreachable("No valid mnemonic for alias?");
+
+ delete Op;
+ delete Op4;
}
}
}
More information about the llvm-commits
mailing list