diff options
author | Chris Lattner <sabre@nondot.org> | 2010-10-29 00:27:31 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-10-29 00:27:31 +0000 |
commit | 14b93851cc7611ae6c2000f1c162592ead954420 (patch) | |
tree | 96e7bc2e5f48768d5e5e4bcbd4625111a3aee0f3 /lib | |
parent | 7b78824fdb85d129860790da308fb876959b4076 (diff) | |
download | llvm-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.td | 6 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 35 |
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)) { |