diff options
author | Tim Northover <tnorthover@apple.com> | 2016-07-11 22:29:37 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2016-07-11 22:29:37 +0000 |
commit | 3e0361710a035f000fb24d434743268fe40f4c08 (patch) | |
tree | bfb4685ed4ed3c835733d332adc9e27f09c6ca5b /llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | |
parent | 5675c9698775b9c29254aa46de216705576cc3c4 (diff) | |
download | bcm5719-llvm-3e0361710a035f000fb24d434743268fe40f4c08.tar.gz bcm5719-llvm-3e0361710a035f000fb24d434743268fe40f4c08.zip |
ARM: validate immediate branch targets in AsmParser.
Immediate branch targets aren't commonly used, but if they are we should make
sure they can actually be encoded. This means they must be divisible by 2 when
targeting Thumb mode, and by 4 when targeting ARM mode.
Also do a little naming cleanup while I was changing everything around anyway.
llvm-svn: 275116
Diffstat (limited to 'llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b3b0dffb6c9..d368e2349b3 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -676,6 +676,24 @@ public: bool isImm() const override { return Kind == k_Immediate; } + + bool isARMBranchTarget() const { + if (!isImm()) return false; + + if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) + return CE->getValue() % 4 == 0; + return true; + } + + + bool isThumbBranchTarget() const { + if (!isImm()) return false; + + if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) + return CE->getValue() % 2 == 0; + return true; + } + // checks whether this operand is an unsigned offset which fits is a field // of specified width and scaled by a specific number of bits template<unsigned width, unsigned scale> @@ -1728,6 +1746,16 @@ public: Inst.addOperand(MCOperand::createExpr(Expr)); } + void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + addExpr(Inst, getImm()); + } + + void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + addExpr(Inst, getImm()); + } + void addCondCodeOperands(MCInst &Inst, unsigned N) const { assert(N == 2 && "Invalid number of operands!"); Inst.addOperand(MCOperand::createImm(unsigned(getCondCode()))); |