Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -709,14 +709,40 @@ return MCDisassembler::Success; } + /// readInstruction16 - read two bytes from the MemoryObject + /// and return 16 bit halfword. +static DecodeStatus readInstruction16(const MemoryObject ®ion, + uint64_t address, + uint64_t &size, + uint32_t &insn, + bool isBigEndian) { + uint8_t Bytes[2]; + + // We want to read exactly 2 Bytes of data. + if (region.readBytes(address, 2, Bytes) == -1) { + size = 0; + return MCDisassembler::Fail; + } + + if (isBigEndian) { + insn = (Bytes[0] << 8) | Bytes[1]; + } else { + // Little-endian byte ordering: + // mips32r2: 4 | 3 | 2 | 1 + // microMIPS: 2 | 1 | 4 | 3 + insn = (Bytes[1] << 8) | Bytes[0]; + } + + return MCDisassembler::Success; +} + /// readInstruction - read four bytes from the MemoryObject /// and return 32 bit word sorted according to the given endianess static DecodeStatus readInstruction32(const MemoryObject ®ion, uint64_t address, uint64_t &size, uint32_t &insn, - bool isBigEndian, - bool IsMicroMips) { + bool isBigEndian) { uint8_t Bytes[4]; // We want to read exactly 4 Bytes of data. @@ -734,20 +760,10 @@ } else { // Encoded as a small-endian 32-bit word in the stream. - // 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); - } + insn = (Bytes[0] << 0) | + (Bytes[1] << 8) | + (Bytes[2] << 16) | + (Bytes[3] << 24); } return MCDisassembler::Success; @@ -760,15 +776,34 @@ uint64_t Address, raw_ostream &vStream, raw_ostream &cStream) const { - uint32_t Insn; + uint32_t Insn = 0; - DecodeStatus Result = readInstruction32(Region, Address, Size, - Insn, isBigEndian, IsMicroMips); - if (Result == MCDisassembler::Fail) - return MCDisassembler::Fail; + DecodeStatus Result; if (IsMicroMips) { - DEBUG(dbgs() << "Trying MicroMips32 table (32-bit opcodes):\n"); + Result = readInstruction16(Region, Address, Size, Insn, isBigEndian); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); + // Calling the auto-generated decoder function. + Result = decodeInstruction(DecoderTableMicroMips16, instr, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) { + Size = 2; + return Result; + } + + uint32_t Insn1 = 0; + Address += 2; + + Result = readInstruction16(Region, Address, Size, Insn1, isBigEndian); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + Insn = (Insn << 16) | Insn1; + + DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); // Calling the auto-generated decoder function. Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address, this, STI); @@ -779,6 +814,10 @@ return MCDisassembler::Fail; } + Result = readInstruction32(Region, Address, Size, Insn, isBigEndian); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (hasCOP3()) { DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); Result = @@ -831,7 +870,7 @@ uint32_t Insn; DecodeStatus Result = readInstruction32(Region, Address, Size, - Insn, isBigEndian, false); + Insn, isBigEndian); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; @@ -879,7 +918,18 @@ unsigned RegNo, uint64_t Address, const void *Decoder) { - return MCDisassembler::Fail; + if (RegNo > 7) + return MCDisassembler::Fail; + + if (RegNo == 0) + RegNo = 16; + else if (RegNo == 1) + RegNo = 17; + + unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); + + Inst.addOperand(MCOperand::CreateReg(Reg)); + return MCDisassembler::Success; } static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, Index: test/MC/Disassembler/Mips/micromips.txt =================================================================== --- test/MC/Disassembler/Mips/micromips.txt +++ test/MC/Disassembler/Mips/micromips.txt @@ -294,3 +294,51 @@ # CHECK: sc $2, 8($4) 0x60 0x44 0xb0 0x08 + +# CHECK: addu16 $6, $17, $4 +0x07 0x42 + +# CHECK: subu16 $5, $16, $3 +0x06 0xb1 + +# CHECK: and16 $16, $2 +0x44 0x82 + +# CHECK: not16 $17, $3 +0x44 0x0b + +# CHECK: or16 $16, $4 +0x44 0xc4 + +# CHECK: xor16 $17, $5 +0x44 0x4d + +# CHECK: sll16 $3, $16, 5 +0x25 0x8a + +# CHECK: srl16 $4, $17, 6 +0x26 0x1d + +# CHECK: mfhi $9 +0x46 0x09 + +# CHECK: mflo $9 +0x46 0x49 + +# CHECK: move $25, $1 +0x0f 0x21 + +# CHECK: jrc $9 +0x45 0xa9 + +# CHECK: jalr $9 +0x45 0xc9 + +# CHECK: jalrs16 $9 +0x45 0xe9 + +# CHECK: move $zero, $zero +0x0c 0x00 + +# CHECK: jr16 $9 +0x45 0x89 Index: test/MC/Disassembler/Mips/micromips_le.txt =================================================================== --- test/MC/Disassembler/Mips/micromips_le.txt +++ test/MC/Disassembler/Mips/micromips_le.txt @@ -294,3 +294,51 @@ # CHECK: sc $2, 8($4) 0x44 0x60 0x08 0xb0 + +# CHECK: addu16 $6, $17, $4 +0x42 0x07 + +# CHECK: subu16 $5, $16, $3 +0xb1 0x06 + +# CHECK: and16 $16, $2 +0x82 0x44 + +# CHECK: not16 $17, $3 +0x0b 0x44 + +# CHECK: or16 $16, $4 +0xc4 0x44 + +# CHECK: xor16 $17, $5 +0x4d 0x44 + +# CHECK: sll16 $3, $16, 5 +0x8a 0x25 + +# CHECK: srl16 $4, $17, 6 +0x1d 0x26 + +# CHECK: mfhi $9 +0x09 0x46 + +# CHECK: mflo $9 +0x49 0x46 + +# CHECK: move $25, $1 +0x21 0x0f + +# CHECK: jrc $9 +0xa9 0x45 + +# CHECK: jalr $9 +0xc9 0x45 + +# CHECK: jalrs16 $9 +0xe9 0x45 + +# CHECK: move $zero, $zero +0x00 0x0c + +# CHECK: jr16 $9 +0x89 0x45