summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-10-29 00:27:31 +0000
committerChris Lattner <sabre@nondot.org>2010-10-29 00:27:31 +0000
commit14b93851cc7611ae6c2000f1c162592ead954420 (patch)
tree96e7bc2e5f48768d5e5e4bcbd4625111a3aee0f3 /lib
parent7b78824fdb85d129860790da308fb876959b4076 (diff)
downloadllvm-14b93851cc7611ae6c2000f1c162592ead954420.tar.gz
llvm-14b93851cc7611ae6c2000f1c162592ead954420.tar.bz2
llvm-14b93851cc7611ae6c2000f1c162592ead954420.tar.xz
add simple support for addrmode5 operands, allowing
vldr.64 to work. I have no idea if this is fully right, but it is in the right direction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117626 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td6
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp35
2 files changed, 31 insertions, 10 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index dd38119c31..40c099e6af 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -456,12 +456,18 @@ def addrmode4 : Operand<i32>,
let MIOperandInfo = (ops GPR:$addr, i32imm);
}
+def ARMMemMode5AsmOperand : AsmOperandClass {
+ let Name = "MemMode5";
+ let SuperClasses = [];
+}
+
// addrmode5 := reg +/- imm8*4
//
def addrmode5 : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrMode5", []> {
let PrintMethod = "printAddrMode5Operand";
let MIOperandInfo = (ops GPR:$base, i32imm);
+ let ParserMatchClass = ARMMemMode5AsmOperand;
}
// addrmode6 := reg with optional writeback
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 88b2c61604..648b54a033 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -153,9 +153,6 @@ public:
};
- //ARMOperand(KindTy K, SMLoc S, SMLoc E)
- // : Kind(K), StartLoc(S), EndLoc(E) {}
-
ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
Kind = o.Kind;
StartLoc = o.StartLoc;
@@ -205,16 +202,16 @@ public:
}
bool isCondCode() const { return Kind == CondCode; }
-
bool isImm() const { return Kind == Immediate; }
-
bool isReg() const { return Kind == Register; }
-
- bool isToken() const {return Kind == Token; }
+ bool isToken() const { return Kind == Token; }
+ bool isMemory() const { return Kind == Memory; }
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
- // Add as immediates when possible.
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
+ // Add as immediates when possible. Null MCExpr = 0.
+ if (Expr == 0)
+ Inst.addOperand(MCOperand::CreateImm(0));
+ else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
else
Inst.addOperand(MCOperand::CreateExpr(Expr));
@@ -236,6 +233,24 @@ public:
assert(N == 1 && "Invalid number of operands!");
addExpr(Inst, getImm());
}
+
+
+ bool isMemMode5() const {
+ // FIXME: Is this right? What about postindexed and Writeback?
+ if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
+ Mem.Preindexed || Mem.Negative)
+ return false;
+
+ return true;
+ }
+
+ void addMemMode5Operands(MCInst &Inst, unsigned N) const {
+ assert(N == 2 && isMemMode5() && "Invalid number of operands!");
+
+ Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
+ assert(!Mem.OffsetIsReg && "invalid mode 5 operand");
+ addExpr(Inst, Mem.Offset);
+ }
virtual void dump(raw_ostream &OS) const;
@@ -508,7 +523,7 @@ ARMOperand *ARMAsmParser::ParseMemory() {
bool OffsetRegShifted = false;
enum ShiftType ShiftType;
const MCExpr *ShiftAmount;
- const MCExpr *Offset;
+ const MCExpr *Offset = 0;
const AsmToken &NextTok = Parser.getTok();
if (NextTok.isNot(AsmToken::EndOfStatement)) {