From 7b2958392c2be221ff1f0d2ffd45d453dec515dd Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Wed, 27 Jul 2011 23:36:57 +0000 Subject: [PATCH] Refactor and improve the encodings/decodings for addrmode3 loads, and make the writeback operand always the first. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136295 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 49 +++++++++++++++---- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 +- .../ARM/Disassembler/ARMDisassemblerCore.cpp | 11 +---- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 722fff7d1c5..6641cbd073b 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:$Rt, GPR:$Rt2, GPR:$Rn_wb), +def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2), (ins addrmode3:$addr), IndexModePre, LdMiscFrm, IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, $addr!", @@ -1904,8 +1904,9 @@ def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 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:$Rt, GPR:$Rt2, GPR:$Rn_wb), +def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn, am3offset:$offset), IndexModePost, LdMiscFrm, IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, [$Rn], $offset", @@ -1917,6 +1918,7 @@ def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 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 @@ -1953,17 +1955,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:$Rt, GPR:$base_wb), +def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt), (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:$Rt, GPR:$base_wb), +def LDRHT : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt), (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:$Rt, GPR:$base_wb), +def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt), (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, "ldrsht", "\t$Rt, $addr", "$addr.base = $base_wb", []> { let Inst{21} = 1; // overwrite @@ -1981,7 +1983,10 @@ 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]>; + "strd", "\t$Rt, $src2, $addr", []>, + Requires<[IsARM, HasV5TE]> { + let Inst{21} = 0; +} // Indexed stores def STR_PRE_REG : AI2stridx_reg<0, 1, (outs GPR:$Rn_wb), @@ -2070,14 +2075,38 @@ 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", []>; + "$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"; +} // 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", []>; + "$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"; +} } // 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 bbeec1cac43..fd19d671d94 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1919,11 +1919,9 @@ 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 1f3920bd8cf..e8c2102c3d6 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 && isStore) { + if (isPrePost) { assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID && "Reg operand expected"); MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, @@ -1485,15 +1485,6 @@ 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;