diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 42e91f4091b..c182142de3c 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1863,7 +1863,7 @@ defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>; } multiclass AI3_ldridx op, bit op20, string opc, InstrItinClass itin> { - def _PRE : AI3ldstidx { @@ -1874,7 +1874,7 @@ multiclass AI3_ldridx op, bit op20, string opc, InstrItinClass itin> { let Inst{11-8} = addr{7-4}; // imm7_4/zero let Inst{3-0} = addr{3-0}; // imm3_0/Rm } - def _POST : AI3ldstidx { @@ -1893,7 +1893,7 @@ defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>; defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>; defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>; let hasExtraDefRegAllocReq = 1 in { -def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2), +def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), (ins addrmode3:$addr), IndexModePre, LdMiscFrm, IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, $addr!", @@ -1904,9 +1904,8 @@ def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2), let Inst{19-16} = addr{12-9}; // Rn let Inst{11-8} = addr{7-4}; // imm7_4/zero let Inst{3-0} = addr{3-0}; // imm3_0/Rm - let DecoderMethod = "DecodeAddrMode3Instruction"; } -def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2), +def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), (ins GPR:$Rn, am3offset:$offset), IndexModePost, LdMiscFrm, IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, [$Rn], $offset", @@ -1918,7 +1917,6 @@ def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2), let Inst{19-16} = Rn; let Inst{11-8} = offset{7-4}; // imm7_4/zero let Inst{3-0} = offset{3-0}; // imm3_0/Rm - let DecoderMethod = "DecodeAddrMode3Instruction"; } } // hasExtraDefRegAllocReq = 1 } // mayLoad = 1, neverHasSideEffects = 1 @@ -1955,17 +1953,17 @@ def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), let Inst{11-0} = addr{11-0}; let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2"; } -def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt), +def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, "ldrsbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { let Inst{21} = 1; // overwrite } -def LDRHT : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt), +def LDRHT : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, "ldrht", "\t$Rt, $addr", "$addr.base = $base_wb", []> { let Inst{21} = 1; // overwrite } -def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt), +def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, "ldrsht", "\t$Rt, $addr", "$addr.base = $base_wb", []> { let Inst{21} = 1; // overwrite @@ -1983,10 +1981,7 @@ def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm, let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr), StMiscFrm, IIC_iStore_d_r, - "strd", "\t$Rt, $src2, $addr", []>, - Requires<[IsARM, HasV5TE]> { - let Inst{21} = 0; -} + "strd", "\t$Rt, $src2, $addr", []>, Requires<[IsARM, HasV5TE]>; // Indexed stores def STR_PRE_REG : AI2stridx_reg<0, 1, (outs GPR:$Rn_wb), @@ -2075,38 +2070,14 @@ def STRD_PRE : AI3stdpr<(outs GPR:$base_wb), (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset), StMiscFrm, IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base, $offset]!", - "$base = $base_wb", []> { - bits<4> src1; - bits<4> base; - bits<10> offset; - let Inst{23} = offset{8}; // U bit - let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm - let Inst{19-16} = base; - let Inst{15-12} = src1; - let Inst{11-8} = offset{7-4}; - let Inst{3-0} = offset{3-0}; - - let DecoderMethod = "DecodeAddrMode3Instruction"; -} + "$base = $base_wb", []>; // For disassembly only def STRD_POST: AI3stdpo<(outs GPR:$base_wb), (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset), StMiscFrm, IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base], $offset", - "$base = $base_wb", []> { - bits<4> src1; - bits<4> base; - bits<10> offset; - let Inst{23} = offset{8}; // U bit - let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm - let Inst{19-16} = base; - let Inst{15-12} = src1; - let Inst{11-8} = offset{7-4}; - let Inst{3-0} = offset{3-0}; - - let DecoderMethod = "DecodeAddrMode3Instruction"; -} + "$base = $base_wb", []>; } // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 // STRT, STRBT, and STRHT are for disassembly only. diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index fd19d671d94..bbeec1cac43 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1919,9 +1919,11 @@ cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, bool ARMAsmParser:: cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &Operands) { + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + // Create a writeback register dummy placeholder. Inst.addOperand(MCOperand::CreateImm(0)); - ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); return true; diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index e8c2102c3d6..1f3920bd8cf 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -1460,7 +1460,7 @@ static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, && "Invalid arguments"); // Operand 0 of a pre- and post-indexed store is the address base writeback. - if (isPrePost) { + if (isPrePost && isStore) { assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID && "Reg operand expected"); MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, @@ -1485,6 +1485,15 @@ static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, ++OpIdx; } + // After dst of a pre- and post-indexed load is the address base writeback. + if (isPrePost && !isStore) { + assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID && + "Reg operand expected"); + MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, + decodeRn(insn)))); + ++OpIdx; + } + // Disassemble the base operand. if (OpIdx >= NumOps) return false;