From 9a11fba79f93aad7765d394c7d062e0678efdbf8 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 1 Oct 2014 08:26:55 +0000 Subject: [PATCH] [mips] Fix disassembly of [ls][wd]c[23], cache, and pref Fixes PR21015, and PR20993. Patch by Jun Koi git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218745 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Mips/Disassembler/MipsDisassembler.cpp | 66 +++++++++++++++++++ lib/Target/Mips/MipsInstrFPU.td | 48 +++++++++++--- lib/Target/Mips/MipsInstrInfo.td | 10 +-- test/MC/Disassembler/Mips/mips2.txt | 13 ++++ test/MC/Disassembler/Mips/mips32.txt | 13 ++++ test/MC/Disassembler/Mips/mips64.txt | 6 ++ 6 files changed, 144 insertions(+), 12 deletions(-) create mode 100644 test/MC/Disassembler/Mips/mips2.txt diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 1bf573b2d42..53fb7a10ad0 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -250,6 +250,11 @@ static DecodeStatus DecodeMem(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeCacheOp(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -267,6 +272,14 @@ static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -964,6 +977,23 @@ static DecodeStatus DecodeMem(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeCacheOp(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<16>(Insn & 0xffff); + unsigned Hint = fieldFromInstruction(Insn, 16, 5); + unsigned Base = fieldFromInstruction(Insn, 21, 5); + + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::CreateReg(Base)); + Inst.addOperand(MCOperand::CreateImm(Offset)); + Inst.addOperand(MCOperand::CreateImm(Hint)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); @@ -1067,6 +1097,42 @@ static DecodeStatus DecodeFMem(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeFMem2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<16>(Insn & 0xffff); + unsigned Reg = fieldFromInstruction(Insn, 16, 5); + unsigned Base = fieldFromInstruction(Insn, 21, 5); + + Reg = getReg(Decoder, Mips::COP2RegClassID, 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 DecodeFMem3(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<16>(Insn & 0xffff); + unsigned Reg = fieldFromInstruction(Insn, 16, 5); + unsigned Base = fieldFromInstruction(Insn, 21, 5); + + Reg = getReg(Decoder, Mips::COP3RegClassID, 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 DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 29d8e30be48..1100e1e0323 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -178,6 +178,38 @@ class SW_FT : + InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> { + let DecoderMethod = "DecodeFMem2"; + let mayStore = 1; +} + +class LW_FT2 : + InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> { + let DecoderMethod = "DecodeFMem2"; + let mayLoad = 1; +} + +class SW_FT3 : + InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> { + let DecoderMethod = "DecodeFMem3"; + let mayStore = 1; +} + +class LW_FT3 : + InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> { + let DecoderMethod = "DecodeFMem3"; + let mayLoad = 1; +} + class MADDS_FT : InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), @@ -407,24 +439,24 @@ def SDC1 : MMRel, SW_FT<"sdc1", AFGR64Opnd, II_SDC1, store>, LW_FM<0x3d>, // Cop2 Memory Instructions // FIXME: These aren't really FPU instructions and as such don't belong in this // file -def LWC2 : LW_FT<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>, +def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>, ISA_MIPS1_NOT_32R6_64R6; -def SWC2 : SW_FT<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>, +def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6; -def LDC2 : LW_FT<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>, +def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>, ISA_MIPS2_NOT_32R6_64R6; -def SDC2 : SW_FT<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>, +def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6; // Cop3 Memory Instructions // FIXME: These aren't really FPU instructions and as such don't belong in this // file let DecoderNamespace = "COP3_" in { - def LWC3 : LW_FT<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>; - def SWC3 : SW_FT<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>; - def LDC3 : LW_FT<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>, + def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>; + def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>; + def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>, ISA_MIPS2; - def SDC3 : SW_FT<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>, + def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>, ISA_MIPS2; } diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 138f70386e7..0a7fc7d94ee 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -1415,13 +1415,15 @@ def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>; def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>; def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>; -class CacheOp : +class CacheOp : InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint), - !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther>; + !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther> { + let DecoderMethod = "DecodeCacheOp"; +} -def CACHE : CacheOp<"cache", mem, GPR32Opnd>, CACHEOP_FM<0b101111>, +def CACHE : CacheOp<"cache", mem>, CACHEOP_FM<0b101111>, INSN_MIPS3_32_NOT_32R6_64R6; -def PREF : CacheOp<"pref", mem, GPR32Opnd>, CACHEOP_FM<0b110011>, +def PREF : CacheOp<"pref", mem>, CACHEOP_FM<0b110011>, INSN_MIPS3_32_NOT_32R6_64R6; //===----------------------------------------------------------------------===// diff --git a/test/MC/Disassembler/Mips/mips2.txt b/test/MC/Disassembler/Mips/mips2.txt new file mode 100644 index 00000000000..a604055e62e --- /dev/null +++ b/test/MC/Disassembler/Mips/mips2.txt @@ -0,0 +1,13 @@ +# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips2 | FileCheck %s + +# CHECK: sdc3 $5, 9154($6) +0xfc 0xc5 0x23 0xc2 + +# CHECK: swc3 $6, 9158($7) +0xec 0xe6 0x23 0xc6 + +# CHECK: ldc3 $7, 9162($8) +0xdd 0x07 0x23 0xca + +# CHECK: lwc3 $8, 9166($9) +0xcd 0x28 0x23 0xce diff --git a/test/MC/Disassembler/Mips/mips32.txt b/test/MC/Disassembler/Mips/mips32.txt index bfb145e3959..bd4ae4daad0 100644 --- a/test/MC/Disassembler/Mips/mips32.txt +++ b/test/MC/Disassembler/Mips/mips32.txt @@ -1,4 +1,5 @@ # RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux | FileCheck %s + # CHECK: abs.d $f12, $f14 0x46 0x20 0x73 0x05 @@ -436,3 +437,15 @@ # CHECK: rdhwr $5, $29 # CHECK: .set pop 0x7c 0x05 0xe8 0x3b + +# CHECK: cache 1, 2($3) +0xbc 0x61 0x00 0x02 + +# CHECK: pref 3, 4($2) +0xcc 0x43 0x00 0x04 + +# CHECK: swc2 $9, 9158($7) +0xe8 0xe9 0x23 0xc6 + +# CHECK: lwc2 $8, 9162($6) +0xc8 0xc8 0x23 0xca diff --git a/test/MC/Disassembler/Mips/mips64.txt b/test/MC/Disassembler/Mips/mips64.txt index f3d2d100cae..d494df6f9c2 100644 --- a/test/MC/Disassembler/Mips/mips64.txt +++ b/test/MC/Disassembler/Mips/mips64.txt @@ -85,3 +85,9 @@ # CHECK: sdxc1 $f8, $4($25) 0x4f 0x24 0x40 0x09 + +# CHECK: sdc2 $9, 9158($7) +0xf8 0xe9 0x23 0xc6 + +# CHECK: ldc2 $3, 9162($8) +0xd9 0x03 0x23 0xca -- 2.34.1