From a674463aac1d0b5d039da11045ccfab5e849b886 Mon Sep 17 00:00:00 2001 From: Vladimir Medic Date: Fri, 6 Sep 2013 12:30:36 +0000 Subject: [PATCH] This patch adds support for microMIPS disassembler and disassembler make check tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190144 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Mips/Disassembler/MipsDisassembler.cpp | 87 +++++++++- lib/Target/Mips/MicroMipsInstrInfo.td | 23 +-- test/MC/Disassembler/Mips/micromips.txt | 149 ++++++++++++++++++ test/MC/Disassembler/Mips/micromips_le.txt | 149 ++++++++++++++++++ 4 files changed, 391 insertions(+), 17 deletions(-) create mode 100644 test/MC/Disassembler/Mips/micromips.txt create mode 100644 test/MC/Disassembler/Mips/micromips_le.txt diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 6e12a5d5e5c..e2b3fa41822 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -53,12 +53,15 @@ protected: /// MipsDisassembler - a disasembler class for Mips32. class MipsDisassembler : public MipsDisassemblerBase { + bool IsMicroMips; public: /// Constructor - Initializes the disassembler. /// MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, bool bigEndian) : - MipsDisassemblerBase(STI, Info, bigEndian) {} + MipsDisassemblerBase(STI, Info, bigEndian) { + IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; + } /// getInstruction - See MCDisassembler. virtual DecodeStatus getInstruction(MCInst &instr, @@ -182,6 +185,16 @@ static DecodeStatus DecodeMem(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemMMImm12(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMemMMImm16(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -251,7 +264,8 @@ static DecodeStatus readInstruction32(const MemoryObject ®ion, uint64_t address, uint64_t &size, uint32_t &insn, - bool isBigEndian) { + bool isBigEndian, + bool IsMicroMips) { uint8_t Bytes[4]; // We want to read exactly 4 Bytes of data. @@ -269,10 +283,20 @@ static DecodeStatus readInstruction32(const MemoryObject ®ion, } else { // Encoded as a small-endian 32-bit word in the stream. - insn = (Bytes[0] << 0) | - (Bytes[1] << 8) | - (Bytes[2] << 16) | - (Bytes[3] << 24); + // Little-endian byte ordering: + // mips32r2: 4 | 3 | 2 | 1 + // microMIPS: 2 | 1 | 4 | 3 + if (IsMicroMips) { + insn = (Bytes[2] << 0) | + (Bytes[3] << 8) | + (Bytes[0] << 16) | + (Bytes[1] << 24); + } else { + insn = (Bytes[0] << 0) | + (Bytes[1] << 8) | + (Bytes[2] << 16) | + (Bytes[3] << 24); + } } return MCDisassembler::Success; @@ -288,10 +312,21 @@ MipsDisassembler::getInstruction(MCInst &instr, uint32_t Insn; DecodeStatus Result = readInstruction32(Region, Address, Size, - Insn, isBigEndian); + Insn, isBigEndian, IsMicroMips); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; + if (IsMicroMips) { + // Calling the auto-generated decoder function. + Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + return MCDisassembler::Fail; + } + // Calling the auto-generated decoder function. Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, this, STI); @@ -313,7 +348,7 @@ Mips64Disassembler::getInstruction(MCInst &instr, uint32_t Insn; DecodeStatus Result = readInstruction32(Region, Address, Size, - Insn, isBigEndian); + Insn, isBigEndian, false); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; @@ -470,6 +505,42 @@ static DecodeStatus DecodeMem(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeMemMMImm12(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<12>(Insn & 0x0fff); + unsigned Reg = fieldFromInstruction(Insn, 21, 5); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::CreateReg(Base)); + Inst.addOperand(MCOperand::CreateImm(Offset)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeMemMMImm16(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<16>(Insn & 0xffff); + unsigned Reg = fieldFromInstruction(Insn, 21, 5); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::CreateReg(Base)); + Inst.addOperand(MCOperand::CreateImm(Offset)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 2cc55553054..273d3ccd0a4 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -19,6 +19,7 @@ class LoadLeftRightMM { + let DecoderMethod = "DecodeMemMMImm12"; string Constraints = "$src = $rt"; } @@ -26,7 +27,9 @@ class StoreLeftRightMM: InstSE<(outs), (ins RO:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode RO:$rt, addrimm12:$addr)], NoItinerary, FrmI>; + [(OpNode RO:$rt, addrimm12:$addr)], NoItinerary, FrmI> { + let DecoderMethod = "DecodeMemMMImm12"; +} let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { /// Arithmetic Instructions (ALU Immediate) @@ -86,14 +89,16 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { SRLV_FM_MM<0xd0, 0>; /// Load and Store Instructions - aligned - def LB_MM : Load<"lb", GPR32Opnd, sextloadi8>, MMRel, LW_FM_MM<0x7>; - def LBu_MM : Load<"lbu", GPR32Opnd, zextloadi8>, MMRel, LW_FM_MM<0x5>; - def LH_MM : Load<"lh", GPR32Opnd, sextloadi16>, MMRel, LW_FM_MM<0xf>; - def LHu_MM : Load<"lhu", GPR32Opnd, zextloadi16>, MMRel, LW_FM_MM<0xd>; - def LW_MM : Load<"lw", GPR32Opnd>, MMRel, LW_FM_MM<0x3f>; - def SB_MM : Store<"sb", GPR32Opnd, truncstorei8>, MMRel, LW_FM_MM<0x6>; - def SH_MM : Store<"sh", GPR32Opnd, truncstorei16>, MMRel, LW_FM_MM<0xe>; - def SW_MM : Store<"sw", GPR32Opnd>, MMRel, LW_FM_MM<0x3e>; + let DecoderMethod = "DecodeMemMMImm16" in { + def LB_MM : Load<"lb", GPR32Opnd>, MMRel, LW_FM_MM<0x7>; + def LBu_MM : Load<"lbu", GPR32Opnd>, MMRel, LW_FM_MM<0x5>; + def LH_MM : Load<"lh", GPR32Opnd>, MMRel, LW_FM_MM<0xf>; + def LHu_MM : Load<"lhu", GPR32Opnd>, MMRel, LW_FM_MM<0xd>; + def LW_MM : Load<"lw", GPR32Opnd>, MMRel, LW_FM_MM<0x3f>; + def SB_MM : Store<"sb", GPR32Opnd>, MMRel, LW_FM_MM<0x6>; + def SH_MM : Store<"sh", GPR32Opnd>, MMRel, LW_FM_MM<0xe>; + def SW_MM : Store<"sw", GPR32Opnd>, MMRel, LW_FM_MM<0x3e>; + } /// Load and Store Instructions - unaligned def LWL_MM : LoadLeftRightMM<"lwl", MipsLWL, GPR32Opnd, mem_mm_12>, diff --git a/test/MC/Disassembler/Mips/micromips.txt b/test/MC/Disassembler/Mips/micromips.txt new file mode 100644 index 00000000000..0b0c7a05151 --- /dev/null +++ b/test/MC/Disassembler/Mips/micromips.txt @@ -0,0 +1,149 @@ +# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mattr=micromips \ +# RUN: | FileCheck %s + +# CHECK: add $9, $6, $7 +0x00 0xe6 0x49 0x10 + +# CHECK: addi $9, $6, 17767 +0x11 0x26 0x45 0x67 + +# CHECK: addiu $9, $6, -15001 +0x31 0x26 0xc5 0x67 + +# CHECK: addi $9, $6, 17767 +0x11 0x26 0x45 0x67 + +# CHECK: addiu $9, $6, -15001 +0x31 0x26 0xc5 0x67 + +# CHECK: addu $9, $6, $7 +0x00 0xe6 0x49 0x50 + +# CHECK: sub $9, $6, $7 +0x00 0xe6 0x49 0x90 + +# CHECK: subu $4, $3, $5 +0x00 0xa3 0x21 0xd0 + +# CHECK: sub $6, $zero, $7 +0x00 0xe0 0x31 0x90 + +# CHECK: subu $6, $zero, $7 +0x00 0xe0 0x31 0xd0 + +# CHECK: addu $7, $8, $zero +0x00 0x08 0x39 0x50 + +# CHECK: slt $3, $3, $5 +0x00 0xa3 0x1b 0x50 + +# CHECK: slti $3, $3, 103 +0x90 0x63 0x00 0x67 + +# CHECK: slti $3, $3, 103 +0x90 0x63 0x00 0x67 + +# CHECK: sltiu $3, $3, 103 +0xb0 0x63 0x00 0x67 + +# CHECK: sltu $3, $3, $5 +0x00 0xa3 0x1b 0x90 + +# CHECK: and $9, $6, $7 +0x00 0xe6 0x4a 0x50 + +# CHECK: andi $9, $6, 17767 +0xd1 0x26 0x45 0x67 + +# CHECK: andi $9, $6, 17767 +0xd1 0x26 0x45 0x67 + +# CHECK: or $3, $4, $5 +0x00 0xa4 0x1a 0x90 + +# CHECK: ori $9, $6, 17767 +0x51 0x26 0x45 0x67 + +# CHECK: xor $3, $3, $5 +0x00 0xa3 0x1b 0x10 + +# CHECK: xori $9, $6, 17767 +0x71 0x26 0x45 0x67 + +# CHECK: xori $9, $6, 17767 +0x71 0x26 0x45 0x67 + +# CHECK: nor $9, $6, $7 +0x00 0xe6 0x4a 0xd0 + +# CHECK: not $7, $8 +0x00 0x08 0x3a 0xd0 + +# CHECK: mul $9, $6, $7 +0x00 0xe6 0x4a 0x10 + +# CHECK: mult $9, $7 +0x00 0xe9 0x8b 0x3c + +# CHECK: multu $9, $7 +0x00 0xe9 0x9b 0x3c + +# CHECK: sll $4, $3, 7 +0x00 0x83 0x38 0x00 + +# CHECK: sllv $2, $3, $5 +0x00 0x65 0x10 0x10 + +# CHECK: sra $4, $3, 7 +0x00 0x83 0x38 0x80 + +# CHECK: srav $2, $3, $5 +0x00 0x65 0x10 0x90 + +# CHECK: srl $4, $3, 7 +0x00 0x83 0x38 0x40 + +# CHECK: srlv $2, $3, $5 +0x00 0x65 0x10 0x50 + +# CHECK: rotr $9, $6, 7 +0x01 0x26 0x38 0xc0 + +# CHECK: rotrv $9, $6, $7 +0x00 0xc7 0x48 0xd0 + +# CHECK: lb $5, 8($4) +0x1c 0xa4 0x00 0x08 + +# CHECK: lbu $6, 8($4) +0x14 0xc4 0x00 0x08 + +# CHECK: lh $2, 8($4) +0x3c 0x44 0x00 0x08 + +# CHECK: lhu $4, 8($2) +0x34 0x82 0x00 0x08 + +# CHECK: lw $6, 4($5) +0xfc 0xc5 0x00 0x04 + +# CHECK: sb $5, 8($4) +0x18 0xa4 0x00 0x08 + +# CHECK: sh $2, 8($4) +0x38 0x44 0x00 0x08 + +# CHECK: sw $5, 4($6) +0xf8 0xa6 0x00 0x04 + +# CHECK: lwl $4, 16($5) +0x60 0x85 0x00 0x10 + +# CHECK: lwr $4, 16($5) +0x60 0x85 0x10 0x10 + +# CHECK: swl $4, 16($5) +0x60 0x85 0x80 0x10 + +# CHECK: swr $4, 16($5) +0x60 0x85 0x90 0x10 diff --git a/test/MC/Disassembler/Mips/micromips_le.txt b/test/MC/Disassembler/Mips/micromips_le.txt new file mode 100644 index 00000000000..bcefeb49b3d --- /dev/null +++ b/test/MC/Disassembler/Mips/micromips_le.txt @@ -0,0 +1,149 @@ +# RUN: llvm-mc --disassemble %s -triple=mipsel-unknown-linux -mattr=micromips \ +# RUN: | FileCheck %s + +# CHECK: add $9, $6, $7 +0xe6 0x00 0x10 0x49 + +# CHECK: addi $9, $6, 17767 +0x26 0x11 0x67 0x45 + +# CHECK: addiu $9, $6, -15001 +0x26 0x31 0x67 0xc5 + +# CHECK: addi $9, $6, 17767 +0x26 0x11 0x67 0x45 + +# CHECK: addiu $9, $6, -15001 +0x26 0x31 0x67 0xc5 + +# CHECK: addu $9, $6, $7 +0xe6 0x00 0x50 0x49 + +# CHECK: sub $9, $6, $7 +0xe6 0x00 0x90 0x49 + +# CHECK: subu $4, $3, $5 +0xa3 0x00 0xd0 0x21 + +# CHECK: sub $6, $zero, $7 +0xe0 0x00 0x90 0x31 + +# CHECK: subu $6, $zero, $7 +0xe0 0x00 0xd0 0x31 + +# CHECK: addu $7, $8, $zero +0x08 0x00 0x50 0x39 + +# CHECK: slt $3, $3, $5 +0xa3 0x00 0x50 0x1b + +# CHECK: slti $3, $3, 103 +0x63 0x90 0x67 0x00 + +# CHECK: slti $3, $3, 103 +0x63 0x90 0x67 0x00 + +# CHECK: sltiu $3, $3, 103 +0x63 0xb0 0x67 0x00 + +# CHECK: sltu $3, $3, $5 +0xa3 0x00 0x90 0x1b + +# CHECK: and $9, $6, $7 +0xe6 0x00 0x50 0x4a + +# CHECK: andi $9, $6, 17767 +0x26 0xd1 0x67 0x45 + +# CHECK: andi $9, $6, 17767 +0x26 0xd1 0x67 0x45 + +# CHECK: or $3, $4, $5 +0xa4 0x00 0x90 0x1a + +# CHECK: ori $9, $6, 17767 +0x26 0x51 0x67 0x45 + +# CHECK: xor $3, $3, $5 +0xa3 0x00 0x10 0x1b + +# CHECK: xori $9, $6, 17767 +0x26 0x71 0x67 0x45 + +# CHECK: xori $9, $6, 17767 +0x26 0x71 0x67 0x45 + +# CHECK: nor $9, $6, $7 +0xe6 0x00 0xd0 0x4a + +# CHECK: not $7, $8 +0x08 0x00 0xd0 0x3a + +# CHECK: mul $9, $6, $7 +0xe6 0x00 0x10 0x4a + +# CHECK: mult $9, $7 +0xe9 0x00 0x3c 0x8b + +# CHECK: multu $9, $7 +0xe9 0x00 0x3c 0x9b + +# CHECK: sll $4, $3, 7 +0x83 0x00 0x00 0x38 + +# CHECK: sllv $2, $3, $5 +0x65 0x00 0x10 0x10 + +# CHECK: sra $4, $3, 7 +0x83 0x00 0x80 0x38 + +# CHECK: srav $2, $3, $5 +0x65 0x00 0x90 0x10 + +# CHECK: srl $4, $3, 7 +0x83 0x00 0x40 0x38 + +# CHECK: srlv $2, $3, $5 +0x65 0x00 0x50 0x10 + +# CHECK: rotr $9, $6, 7 +0x26 0x01 0xc0 0x38 + +# CHECK: rotrv $9, $6, $7 +0xc7 0x00 0xd0 0x48 + +# CHECK: lb $5, 8($4) +0xa4 0x1c 0x08 0x00 + +# CHECK: lbu $6, 8($4) +0xc4 0x14 0x08 0x00 + +# CHECK: lh $2, 8($4) +0x44 0x3c 0x08 0x00 + +# CHECK: lhu $4, 8($2) +0x82 0x34 0x08 0x00 + +# CHECK: lw $6, 4($5) +0xc5 0xfc 0x04 0x00 + +# CHECK: sb $5, 8($4) +0xa4 0x18 0x08 0x00 + +# CHECK: sh $2, 8($4) +0x44 0x38 0x08 0x00 + +# CHECK: sw $5, 4($6) +0xa6 0xf8 0x04 0x00 + +# CHECK: lwl $4, 16($5) +0x85 0x60 0x10 0x00 + +# CHECK: lwr $4, 16($5) +0x85 0x60 0x10 0x10 + +# CHECK: swl $4, 16($5) +0x85 0x60 0x10 0x80 + +# CHECK: swr $4, 16($5) +0x85 0x60 0x10 0x90 -- 2.34.1