From 462763dc0b4c3f5b7f21d74703a22d5530271ca3 Mon Sep 17 00:00:00 2001 From: Vladimir Medic Date: Mon, 1 Dec 2014 11:12:04 +0000 Subject: [PATCH] The andi16, addiusp and jraddiusp micromips instructions were missing dedicated decoder methods in MipsDisassembler.cpp to properly decode immediate operands. These methods are added together with corresponding tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223006 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Mips/Disassembler/MipsDisassembler.cpp | 39 +++++++++++++++++++ lib/Target/Mips/MicroMipsInstrInfo.td | 3 ++ test/MC/Disassembler/Mips/micromips.txt | 21 ++++++++++ test/MC/Disassembler/Mips/micromips_le.txt | 21 ++++++++++ test/MC/Mips/micromips-16-bit-instructions.s | 12 ++++++ 5 files changed, 96 insertions(+) diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 878bc23dbab..81bbe3003e2 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -340,6 +340,15 @@ static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't /// handle. template @@ -1591,6 +1600,36 @@ static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, return MCDisassembler::Success; } +static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + int32_t DecodedValue; + switch (Insn) { + case 0: DecodedValue = 256; break; + case 1: DecodedValue = 257; break; + case 510: DecodedValue = -258; break; + case 511: DecodedValue = -257; break; + default: DecodedValue = SignExtend32<9>(Insn); break; + } + Inst.addOperand(MCOperand::CreateImm(DecodedValue << 2)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + // Insn must be >= 0, since it is unsigned that condition is always true. + assert(Insn < 16); + int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, + 255, 32768, 65535}; + Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn])); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + Inst.addOperand(MCOperand::CreateImm(Insn << 2)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 209cff1c66a..11ce41adf1d 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -13,6 +13,7 @@ def simm12 : Operand { def uimm5_lsl2 : Operand { let EncoderMethod = "getUImm5Lsl2Encoding"; + let DecoderMethod = "DecodeUImm5lsl2"; } def uimm6_lsl2 : Operand { @@ -22,6 +23,7 @@ def uimm6_lsl2 : Operand { def simm9_addiusp : Operand { let EncoderMethod = "getSImm9AddiuspValue"; + let DecoderMethod = "DecodeSimm9SP"; } def uimm3_shift : Operand { @@ -35,6 +37,7 @@ def simm3_lsa2 : Operand { def uimm4_andi : Operand { let EncoderMethod = "getUImm4AndValue"; + let DecoderMethod = "DecodeANDI16Imm"; } def immSExtAddiur2 : ImmLeaf