From df464ae2248fba821eebda750f3f412f443c36b7 Mon Sep 17 00:00:00 2001 From: Vladimir Medic Date: Thu, 29 Jan 2015 11:33:41 +0000 Subject: [PATCH] [Mips][Disassembler] When disassembler meets cache/pref instructions for r6 it crashes as the access to operands array is out of range. This patch adds dedicated decoder method for R6 CACHE_HINT_DESC class that properly handles decoding of these instructions. llvm-svn: 227430 --- .../Target/Mips/Disassembler/MipsDisassembler.cpp | 22 ++++++++++++++++++++++ llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 1 + .../Mips/mips32r6/valid-mips32r6-el.txt | 2 ++ .../Disassembler/Mips/mips32r6/valid-mips32r6.txt | 3 ++- .../Mips/mips32r6/valid-xfail-mips32r6.txt | 2 -- .../Mips/mips64r6/valid-mips64r6-el.txt | 3 ++- .../Disassembler/Mips/mips64r6/valid-mips64r6.txt | 3 ++- .../Mips/mips64r6/valid-xfail-mips64r6.txt | 2 -- 8 files changed, 31 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 29998e9..9dab45c 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -266,6 +266,11 @@ static DecodeStatus DecodeCacheOp(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeCacheOpR6(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1137,6 +1142,23 @@ static DecodeStatus DecodeCacheOpMM(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeCacheOpR6(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = fieldFromInstruction(Insn, 7, 9); + 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 DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index 2175160..49c6322 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -549,6 +549,7 @@ class CACHE_HINT_DESC Pattern = []; + string DecoderMethod = "DecodeCacheOpR6"; } class CACHE_DESC : CACHE_HINT_DESC<"cache", mem_simm9, GPR32Opnd>; diff --git a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt index 85d1a0e..c10d166 100644 --- a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt +++ b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt @@ -144,3 +144,5 @@ 0x30 0x81 0x79 0x49 # CHECK: swc2 $25, 304($16) 0x00 0x01 0x05 0xf8 # CHECK: jialc $5, 256 0x00 0x01 0x05 0xd8 # CHECK: jic $5, 256 +0x25 0x04 0xa1 0x7c # CHECK: cache 1, 8($5) +0x35 0x04 0xa1 0x7c # CHECK: pref 1, 8($5 diff --git a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt index 3c4d1e2..0b78003 100644 --- a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt +++ b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt @@ -144,4 +144,5 @@ 0x49 0x79 0x81 0x30 # CHECK: swc2 $25, 304($16) 0xf8 0x05 0x01 0x00 # CHECK: jialc $5, 256 0xd8 0x05 0x01 0x00 # CHECK: jic $5, 256 - +0x7c 0xa1 0x04 0x25 # CHECK: cache 1, 8($5) +0x7c 0xa1 0x04 0x35 # CHECK: pref 1, 8($5) diff --git a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-xfail-mips32r6.txt b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-xfail-mips32r6.txt index dc29c0c..e9afd03 100644 --- a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-xfail-mips32r6.txt +++ b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-xfail-mips32r6.txt @@ -13,5 +13,3 @@ 0x60 0xc0 0x00 0x40 # CHECK: bnec $6, $zero, 256 0x60 0xa0 0x00 0x40 # CHECK: bnec $5, $zero, 256 0x60 0xa6 0x00 0x40 # CHECK: bnec $5, $6, 256 -0x7c 0xa1 0x04 0x25 # CHECK: cache 1, 8($5) -0x7c 0xa1 0x04 0x35 # CHECK: pref 1, 8($5) diff --git a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt index 0d83a34..b92c793 100644 --- a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt +++ b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt @@ -162,4 +162,5 @@ 0x30 0x81 0x79 0x49 # CHECK: swc2 $25, 304($16) 0x00 0x01 0x05 0xf8 # CHECK: jialc $5, 256 0x00 0x01 0x05 0xd8 # CHECK: jic $5, 256 - +0x25 0x04 0xa1 0x7c # CHECK: cache 1, 8($5) +0x35 0x04 0xa1 0x7c # CHECK: pref 1, 8($5) diff --git a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt index f4ce8f7..debbe50 100644 --- a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt +++ b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt @@ -162,4 +162,5 @@ 0x49 0x79 0x81 0x30 # CHECK: swc2 $25, 304($16) 0xf8 0x05 0x01 0x00 # CHECK: jialc $5, 256 0xd8 0x05 0x01 0x00 # CHECK: jic $5, 256 - +0x7c 0xa1 0x04 0x25 # CHECK: cache 1, 8($5) +0x7c 0xa1 0x04 0x35 # CHECK: pref 1, 8($5) diff --git a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-xfail-mips64r6.txt b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-xfail-mips64r6.txt index fe38c1f..8ca8b81 100644 --- a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-xfail-mips64r6.txt +++ b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-xfail-mips64r6.txt @@ -13,8 +13,6 @@ 0x60 0xc0 0x00 0x40 # CHECK: bnec $6, $zero, 256 0x60 0xa0 0x00 0x40 # CHECK: bnec $5, $zero, 256 0x60 0xa6 0x00 0x40 # CHECK: bnec $5, $6, 256 -0x7c 0xa1 0x04 0x25 # CHECK: cache 1, 8($5) -0x7c 0xa1 0x04 0x35 # CHECK: pref 1, 8($5) 0x64 0x58 0x46 0x9f # CHECK: daddiu $24, $2, 18079 0x66 0x73 0x69 0x3f # CHECK: daddiu $19, $19, 26943 0x65 0x6f 0xec 0x5f # CHECK: daddiu $15, $11, -5025 -- 2.7.4