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 | 7cdbf086e4676494fc6a5b26c169285ae0bb740b (patch) | |
tree | 3b58a65eef5aba1379f963126818421f15e1908a | |
parent | 11abf5bca973be49ccb1aaff18b6cc0020981247 (diff) | |
download | llvm-7cdbf086e4676494fc6a5b26c169285ae0bb740b.tar.gz llvm-7cdbf086e4676494fc6a5b26c169285ae0bb740b.tar.bz2 llvm-7cdbf086e4676494fc6a5b26c169285ae0bb740b.tar.xz |
Fix decoding of pre-indexed stores.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137487 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 2 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 41 |
2 files changed, 43 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index bfcb0f23d9..2a029ddb20 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -2243,6 +2243,7 @@ multiclass AI2_stridx<bit isByte, string opc, InstrItinClass itin> { let Inst{19-16} = addr{16-13}; // Rn let Inst{11-0} = addr{11-0}; // imm12 let AsmMatchConverter = "cvtStWriteBackRegAddrModeImm12"; + let DecoderMethod = "DecodeSTRPreImm"; } def _PRE_REG : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), @@ -2256,6 +2257,7 @@ multiclass AI2_stridx<bit isByte, string opc, InstrItinClass itin> { let Inst{11-0} = addr{11-0}; let Inst{4} = 0; // Inst{4} = 0 let AsmMatchConverter = "cvtStWriteBackRegAddrMode2"; + let DecoderMethod = "DecodeSTRPreReg"; } def _POST_REG : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 805cf54473..7de0c236ac 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/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; +} |