diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 65 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsRegisterInfo.td | 6 |
2 files changed, 57 insertions, 14 deletions
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 48904ce2dee..118c3b0b293 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -700,6 +700,26 @@ static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, return MCDisassembler::Success; } +/// Read two bytes from the ArrayRef and return 16 bit halfword sorted +/// according to the given endianess. +static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, + uint64_t &Size, uint32_t &Insn, + bool IsBigEndian) { + // We want to read exactly 2 Bytes of data. + if (Bytes.size() < 2) { + Size = 0; + return MCDisassembler::Fail; + } + + if (IsBigEndian) { + Insn = (Bytes[0] << 8) | Bytes[1]; + } else { + Insn = (Bytes[1] << 8) | Bytes[0]; + } + + return MCDisassembler::Success; +} + /// Read four bytes from the ArrayRef and return 32 bit word sorted /// according to the given endianess static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, @@ -711,15 +731,19 @@ static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, return MCDisassembler::Fail; } + // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) + // always precede the low 16 bits in the instruction stream (that is, they + // are placed at lower addresses in the instruction stream). + // + // microMIPS byte ordering: + // Big-endian: 0 | 1 | 2 | 3 + // Little-endian: 1 | 0 | 3 | 2 + if (IsBigEndian) { // Encoded as a big-endian 32-bit word in the stream. Insn = (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); } 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); @@ -738,14 +762,25 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, raw_ostream &VStream, raw_ostream &CStream) const { uint32_t Insn; - - DecodeStatus Result = - readInstruction32(Bytes, 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(Bytes, Address, Size, Insn, IsBigEndian); + + 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; + } + + Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); // Calling the auto-generated decoder function. Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, this, STI); @@ -756,6 +791,10 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, return MCDisassembler::Fail; } + Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (hasCOP3()) { DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); Result = @@ -854,7 +893,11 @@ static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - return MCDisassembler::Fail; + if (RegNo > 7) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); + Inst.addOperand(MCOperand::CreateReg(Reg)); + return MCDisassembler::Success; } static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index 42fe76b2979..cee041fdbd4 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -289,10 +289,10 @@ def GPR32 : GPR32Class<[i32]>; def DSPR : GPR32Class<[v4i8, v2i16]>; def GPRMM16 : RegisterClass<"Mips", [i32], 32, (add - // Return Values and Arguments - V0, V1, A0, A1, A2, A3, // Callee save - S0, S1)>; + S0, S1, + // Return Values and Arguments + V0, V1, A0, A1, A2, A3)>; def GPR64 : RegisterClass<"Mips", [i64], 64, (add // Reserved |