diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-08-11 06:37:20 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-08-11 06:37:20 +0000 |
commit | 345a9a6269318c96f333c0492b23733e29d952df (patch) | |
tree | dc97533a3d180eff05be9b4a7a6eddd2389141af /lib | |
parent | 5747b13af801d5af7cd5827c07c6a59e981bdb1a (diff) | |
download | llvm-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.cpp | 45 |
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); |