diff options
| author | Owen Anderson <resistor@mac.com> | 2011-08-12 18:12:39 +0000 |
|---|---|---|
| committer | Owen Anderson <resistor@mac.com> | 2011-08-12 18:12:39 +0000 |
| commit | 3987a61c16f64982e0364bbdc4203345ff9f6030 (patch) | |
| tree | 8fc8d08d276b56a001756cb949037de643b67fe7 /llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | |
| parent | 2f6b944f563600aa53739c5dd36a9d0b8f60c0cb (diff) | |
| download | llvm-3987a61c16f64982e0364bbdc4203345ff9f6030.zip llvm-3987a61c16f64982e0364bbdc4203345ff9f6030.tar.gz llvm-3987a61c16f64982e0364bbdc4203345ff9f6030.tar.bz2 | |
Fix decoding of pre-indexed stores.
llvm-svn: 137487
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
| -rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 805cf54..7de0c23 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -139,6 +139,11 @@ static bool DecodeDoubleRegLoad(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); static bool DecodeDoubleRegStore(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static bool DecodeSTRPreImm(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); +static bool DecodeSTRPreReg(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + static bool DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn, uint64_t Address, const void *Decoder); @@ -2524,4 +2529,40 @@ static bool DecodeDoubleRegStore(llvm::MCInst &Inst, unsigned Insn, return true; } +static bool DecodeSTRPreImm(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned Rn = fieldFromInstruction32(Insn, 16, 4); + unsigned Rt = fieldFromInstruction32(Insn, 12, 4); + unsigned imm = fieldFromInstruction32(Insn, 0, 12); + imm |= fieldFromInstruction32(Insn, 16, 4) << 13; + imm |= fieldFromInstruction32(Insn, 23, 1) << 12; + unsigned pred = fieldFromInstruction32(Insn, 28, 4); + if (Rn == 0xF || Rn == Rt) return false; // UNPREDICTABLE + + if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false; + if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)) return false; + if (!DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)) return false; + if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false; + + return true; +} + +static bool DecodeSTRPreReg(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned Rn = fieldFromInstruction32(Insn, 16, 4); + unsigned Rt = fieldFromInstruction32(Insn, 12, 4); + unsigned imm = fieldFromInstruction32(Insn, 0, 12); + imm |= fieldFromInstruction32(Insn, 16, 4) << 13; + imm |= fieldFromInstruction32(Insn, 23, 1) << 12; + unsigned pred = fieldFromInstruction32(Insn, 28, 4); + + if (Rn == 0xF || Rn == Rt) return false; // UNPREDICTABLE + + if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false; + if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)) return false; + if (!DecodeSORegMemOperand(Inst, imm, Address, Decoder)) return false; + if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false; + + return true; +} |
