summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-08-11 06:37:20 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-08-11 06:37:20 +0000
commit345a9a6269318c96f333c0492b23733e29d952df (patch)
treedc97533a3d180eff05be9b4a7a6eddd2389141af /lib
parent5747b13af801d5af7cd5827c07c6a59e981bdb1a (diff)
downloadllvm-345a9a6269318c96f333c0492b23733e29d952df.tar.gz
llvm-345a9a6269318c96f333c0492b23733e29d952df.tar.bz2
llvm-345a9a6269318c96f333c0492b23733e29d952df.tar.xz
MC/ARM: Add basic support for handling predication by parsing it out of the mnemonic into a separate operand form.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110794 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp45
1 files changed, 44 insertions, 1 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index b87d45826a..abaf704fa5 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
using namespace llvm;
@@ -221,8 +222,10 @@ public:
}
void addCondCodeOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
+ assert(N == 2 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
+ // FIXME: What belongs here?
+ Inst.addOperand(MCOperand::CreateReg(0));
}
void addRegOperands(MCInst &Inst, unsigned N) const {
@@ -237,6 +240,15 @@ public:
virtual void dump(raw_ostream &OS) const;
+ static void CreateCondCode(OwningPtr<ARMOperand> &Op, ARMCC::CondCodes CC,
+ SMLoc S) {
+ Op.reset(new ARMOperand);
+ Op->Kind = CondCode;
+ Op->CC.Val = CC;
+ Op->StartLoc = S;
+ Op->EndLoc = S;
+ }
+
static void CreateToken(OwningPtr<ARMOperand> &Op, StringRef Str,
SMLoc S) {
Op.reset(new ARMOperand);
@@ -656,9 +668,40 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
size_t Start = 0, Next = Name.find('.');
StringRef Head = Name.slice(Start, Next);
+ // Determine the predicate, if any.
+ //
+ // FIXME: We need a way to check whether a prefix supports predication,
+ // otherwise we will end up with an ambiguity for instructions that happen to
+ // end with a predicate name.
+ unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2))
+ .Case("eq", ARMCC::EQ)
+ .Case("ne", ARMCC::NE)
+ .Case("hs", ARMCC::HS)
+ .Case("lo", ARMCC::LO)
+ .Case("mi", ARMCC::MI)
+ .Case("pl", ARMCC::PL)
+ .Case("vs", ARMCC::VS)
+ .Case("vc", ARMCC::VC)
+ .Case("hi", ARMCC::HI)
+ .Case("ls", ARMCC::LS)
+ .Case("ge", ARMCC::GE)
+ .Case("lt", ARMCC::LT)
+ .Case("gt", ARMCC::GT)
+ .Case("le", ARMCC::LE)
+ .Case("al", ARMCC::AL)
+ .Default(~0U);
+ if (CC != ~0U) {
+ Head = Head.slice(0, Head.size() - 2);
+ } else
+ CC = ARMCC::AL;
+
ARMOperand::CreateToken(Op, Head, NameLoc);
Operands.push_back(Op.take());
+ ARMOperand::CreateCondCode(Op, ARMCC::CondCodes(CC), NameLoc);
+ Operands.push_back(Op.take());
+
+ // Add the remaining tokens in the mnemonic.
while (Next != StringRef::npos) {
Start = Next;
Next = Name.find('.', Start + 1);