From 14c903a76be7933cea746617d3f787fdf4de8203 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 4 Aug 2011 23:18:05 +0000 Subject: [PATCH] Fix broken encodings for the Thumb2 LDRD/STRD instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136942 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrFormats.td | 21 +++++++++++++++++ lib/Target/ARM/ARMInstrThumb2.td | 11 +++++---- .../ARM/Disassembler/ThumbDisassemblerCore.h | 23 +++++++++++-------- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index c3d9e39dfa6..97e807ccc22 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1151,6 +1151,27 @@ class T2Ii8s4 pattern> + : Thumb2I { + bits<4> Rt; + bits<4> Rt2; + bits<4> base; + bits<9> imm; + let Inst{31-25} = 0b1110100; + let Inst{24} = P; + let Inst{23} = imm{8}; + let Inst{22} = 1; + let Inst{21} = W; + let Inst{20} = isLoad; + let Inst{19-16} = base{3-0}; + let Inst{15-12} = Rt{3-0}; + let Inst{11-8} = Rt2{3-0}; + let Inst{7-0} = imm{7-0}; +} + + class T2sI pattern> : Thumb2sI; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index b53ca16c18c..873c3d6426a 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -141,6 +141,7 @@ def t2addrmode_imm8s4 : Operand { def t2am_imm8s4_offset : Operand { let PrintMethod = "printT2AddrModeImm8s4OffsetOperand"; + let DecoderMethod = "DecodeT2Imm8S4"; } // t2addrmode_so_reg := reg + (reg << imm2) @@ -1354,19 +1355,21 @@ def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>; // ldrd / strd pre / post variants // For disassembly only. -def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2), +def t2LDRD_PRE : T2Ii8s4Tied<1, 1, 1, + (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb), (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, [$base, $imm]!", []>; -def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2), +def t2LDRD_POST : T2Ii8s4Tied<0, 1, 1, + (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb), (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, [$base], $imm", []>; -def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs), +def t2STRD_PRE : T2Ii8s4Tied<1, 1, 0, (outs GPR:$wb), (ins rGPR:$Rt, rGPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm), IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base, $imm]!", []>; -def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs), +def t2STRD_POST : T2Ii8s4Tied<0, 1, 0, (outs GPR:$wb), (ins rGPR:$Rt, rGPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm), IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base], $imm", []>; diff --git a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h index 66a62ef5a56..a1b38f377ad 100644 --- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h +++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h @@ -1318,13 +1318,6 @@ static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode, const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo; if (!OpInfo) return false; - assert(NumOps >= 4 - && OpInfo[0].RegClass > 0 - && OpInfo[0].RegClass == OpInfo[1].RegClass - && OpInfo[2].RegClass > 0 - && OpInfo[3].RegClass < 0 - && "Expect >= 4 operands and first 3 as reg operands"); - // Thumnb allows for specifying Rt and Rt2, unlike ARM (which has Rt2==Rt+1). unsigned Rt = decodeRd(insn); unsigned Rt2 = decodeRs(insn); @@ -1357,20 +1350,32 @@ static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode, // Add the operands. unsigned RegClassPair = OpInfo[0].RegClass; unsigned RegClassBase = OpInfo[2].RegClass; - + MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair, decodeRd(insn)))); MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair, decodeRs(insn)))); MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase, decodeRn(insn)))); + unsigned Added = 4; + switch (MI.getOpcode()) { + case ARM::t2LDRD_PRE: + case ARM::t2LDRD_POST: + case ARM::t2STRD_PRE: + case ARM::t2STRD_POST: + MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase, + decodeRn(insn)))); + Added = 5; + default: + break; + } // Finally add (+/-)imm8*4, depending on the U bit. int Offset = getImm8(insn) * 4; if (getUBit(insn) == 0) Offset = -Offset; MI.addOperand(MCOperand::CreateImm(Offset)); - NumOpsAdded = 4; + NumOpsAdded = Added; return true; }