forked from OSchip/llvm-project
[mips] Fix disassembly of [ls][wd]c[23], cache, and pref
Fixes PR21015, and PR20993. Patch by Jun Koi llvm-svn: 218745
This commit is contained in:
parent
7072a7968f
commit
92db6b78f7
|
@ -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,
|
||||
|
|
|
@ -178,6 +178,38 @@ class SW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
|
|||
let mayStore = 1;
|
||||
}
|
||||
|
||||
class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
|
||||
SDPatternOperator OpNode= null_frag> :
|
||||
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<string opstr, RegisterOperand RC, InstrItinClass Itin,
|
||||
SDPatternOperator OpNode= null_frag> :
|
||||
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<string opstr, RegisterOperand RC, InstrItinClass Itin,
|
||||
SDPatternOperator OpNode= null_frag> :
|
||||
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<string opstr, RegisterOperand RC, InstrItinClass Itin,
|
||||
SDPatternOperator OpNode= null_frag> :
|
||||
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<string opstr, RegisterOperand RC, InstrItinClass Itin,
|
||||
SDPatternOperator OpNode = null_frag> :
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<string instr_asm, Operand MemOpnd, RegisterOperand GPROpnd> :
|
||||
class CacheOp<string instr_asm, Operand MemOpnd> :
|
||||
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;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue