mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[Sparc] Add support to disassemble sparc memory instructions.
llvm-svn: 202575
This commit is contained in:
parent
fd8d08b164
commit
1eb4e172be
@ -174,6 +174,22 @@ static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder);
|
||||
static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder);
|
||||
static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder);
|
||||
static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder);
|
||||
static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
|
||||
uint64_t Address, const void *Decoder);
|
||||
static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn,
|
||||
uint64_t Address, const void *Decoder);
|
||||
static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
|
||||
uint64_t Address, const void *Decoder);
|
||||
static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
|
||||
uint64_t Address, const void *Decoder);
|
||||
|
||||
#include "SparcGenDisassemblerTables.inc"
|
||||
|
||||
@ -226,3 +242,97 @@ SparcDisassembler::getInstruction(MCInst &instr,
|
||||
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
|
||||
|
||||
typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,
|
||||
const void *Decoder,
|
||||
bool isLoad, DecodeFunc DecodeRD) {
|
||||
unsigned rd = fieldFromInstruction(insn, 25, 5);
|
||||
unsigned rs1 = fieldFromInstruction(insn, 14, 5);
|
||||
bool isImm = fieldFromInstruction(insn, 13, 1);
|
||||
unsigned rs2 = 0;
|
||||
unsigned simm13 = 0;
|
||||
if (isImm)
|
||||
simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
|
||||
else
|
||||
rs2 = fieldFromInstruction(insn, 0, 5);
|
||||
|
||||
DecodeStatus status;
|
||||
if (isLoad) {
|
||||
status = DecodeRD(MI, rd, Address, Decoder);
|
||||
if (status != MCDisassembler::Success)
|
||||
return status;
|
||||
}
|
||||
|
||||
// Decode rs1.
|
||||
status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
|
||||
if (status != MCDisassembler::Success)
|
||||
return status;
|
||||
|
||||
// Decode imm|rs2.
|
||||
if (isImm)
|
||||
MI.addOperand(MCOperand::CreateImm(simm13));
|
||||
else {
|
||||
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
|
||||
if (status != MCDisassembler::Success)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!isLoad) {
|
||||
status = DecodeRD(MI, rd, Address, Decoder);
|
||||
if (status != MCDisassembler::Success)
|
||||
return status;
|
||||
}
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return DecodeMem(Inst, insn, Address, Decoder, true,
|
||||
DecodeIntRegsRegisterClass);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return DecodeMem(Inst, insn, Address, Decoder, true,
|
||||
DecodeFPRegsRegisterClass);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return DecodeMem(Inst, insn, Address, Decoder, true,
|
||||
DecodeDFPRegsRegisterClass);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return DecodeMem(Inst, insn, Address, Decoder, true,
|
||||
DecodeQFPRegsRegisterClass);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
|
||||
uint64_t Address, const void *Decoder) {
|
||||
return DecodeMem(Inst, insn, Address, Decoder, false,
|
||||
DecodeIntRegsRegisterClass);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return DecodeMem(Inst, insn, Address, Decoder, false,
|
||||
DecodeFPRegsRegisterClass);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
|
||||
uint64_t Address, const void *Decoder) {
|
||||
return DecodeMem(Inst, insn, Address, Decoder, false,
|
||||
DecodeDFPRegsRegisterClass);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
|
||||
uint64_t Address, const void *Decoder) {
|
||||
return DecodeMem(Inst, insn, Address, Decoder, false,
|
||||
DecodeQFPRegsRegisterClass);
|
||||
}
|
||||
|
@ -235,7 +235,8 @@ def UDIVXri : F3_2<2, 0b001101,
|
||||
let Predicates = [Is64Bit] in {
|
||||
|
||||
// 64-bit loads.
|
||||
defm LDX : Load<"ldx", 0b001011, load, I64Regs, i64>;
|
||||
let DecoderMethod = "DecodeLoadInt" in
|
||||
defm LDX : Load<"ldx", 0b001011, load, I64Regs, i64>;
|
||||
|
||||
let mayLoad = 1, isCodeGenOnly = 1, isAsmParserOnly = 1 in
|
||||
def TLS_LDXrr : F3_1<3, 0b001011,
|
||||
@ -270,10 +271,12 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr ADDRrr:$addr)>;
|
||||
def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>;
|
||||
|
||||
// Sign-extending load of i32 into i64 is a new SPARC v9 instruction.
|
||||
defm LDSW : Load<"ldsw", 0b001000, sextloadi32, I64Regs, i64>;
|
||||
let DecoderMethod = "DecodeLoadInt" in
|
||||
defm LDSW : Load<"ldsw", 0b001000, sextloadi32, I64Regs, i64>;
|
||||
|
||||
// 64-bit stores.
|
||||
defm STX : Store<"stx", 0b001110, store, I64Regs, i64>;
|
||||
let DecoderMethod = "DecodeStoreInt" in
|
||||
defm STX : Store<"stx", 0b001110, store, I64Regs, i64>;
|
||||
|
||||
// Truncating stores from i64 are identical to the i32 stores.
|
||||
def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>;
|
||||
|
@ -387,28 +387,38 @@ let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
|
||||
}
|
||||
|
||||
// Section B.1 - Load Integer Instructions, p. 90
|
||||
defm LDSB : Load<"ldsb", 0b001001, sextloadi8, IntRegs, i32>;
|
||||
defm LDSH : Load<"ldsh", 0b001010, sextloadi16, IntRegs, i32>;
|
||||
defm LDUB : Load<"ldub", 0b000001, zextloadi8, IntRegs, i32>;
|
||||
defm LDUH : Load<"lduh", 0b000010, zextloadi16, IntRegs, i32>;
|
||||
defm LD : Load<"ld", 0b000000, load, IntRegs, i32>;
|
||||
let DecoderMethod = "DecodeLoadInt" in {
|
||||
defm LDSB : Load<"ldsb", 0b001001, sextloadi8, IntRegs, i32>;
|
||||
defm LDSH : Load<"ldsh", 0b001010, sextloadi16, IntRegs, i32>;
|
||||
defm LDUB : Load<"ldub", 0b000001, zextloadi8, IntRegs, i32>;
|
||||
defm LDUH : Load<"lduh", 0b000010, zextloadi16, IntRegs, i32>;
|
||||
defm LD : Load<"ld", 0b000000, load, IntRegs, i32>;
|
||||
}
|
||||
|
||||
// Section B.2 - Load Floating-point Instructions, p. 92
|
||||
defm LDF : Load<"ld", 0b100000, load, FPRegs, f32>;
|
||||
defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64>;
|
||||
defm LDQF : Load<"ldq", 0b100010, load, QFPRegs, f128>,
|
||||
Requires<[HasV9, HasHardQuad]>;
|
||||
let DecoderMethod = "DecodeLoadFP" in
|
||||
defm LDF : Load<"ld", 0b100000, load, FPRegs, f32>;
|
||||
let DecoderMethod = "DecodeLoadDFP" in
|
||||
defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64>;
|
||||
let DecoderMethod = "DecodeLoadQFP" in
|
||||
defm LDQF : Load<"ldq", 0b100010, load, QFPRegs, f128>,
|
||||
Requires<[HasV9, HasHardQuad]>;
|
||||
|
||||
// Section B.4 - Store Integer Instructions, p. 95
|
||||
defm STB : Store<"stb", 0b000101, truncstorei8, IntRegs, i32>;
|
||||
defm STH : Store<"sth", 0b000110, truncstorei16, IntRegs, i32>;
|
||||
defm ST : Store<"st", 0b000100, store, IntRegs, i32>;
|
||||
let DecoderMethod = "DecodeStoreInt" in {
|
||||
defm STB : Store<"stb", 0b000101, truncstorei8, IntRegs, i32>;
|
||||
defm STH : Store<"sth", 0b000110, truncstorei16, IntRegs, i32>;
|
||||
defm ST : Store<"st", 0b000100, store, IntRegs, i32>;
|
||||
}
|
||||
|
||||
// Section B.5 - Store Floating-point Instructions, p. 97
|
||||
defm STF : Store<"st", 0b100100, store, FPRegs, f32>;
|
||||
defm STDF : Store<"std", 0b100111, store, DFPRegs, f64>;
|
||||
defm STQF : Store<"stq", 0b100110, store, QFPRegs, f128>,
|
||||
Requires<[HasV9, HasHardQuad]>;
|
||||
let DecoderMethod = "DecodeStoreFP" in
|
||||
defm STF : Store<"st", 0b100100, store, FPRegs, f32>;
|
||||
let DecoderMethod = "DecodeStoreDFP" in
|
||||
defm STDF : Store<"std", 0b100111, store, DFPRegs, f64>;
|
||||
let DecoderMethod = "DecodeStoreQFP" in
|
||||
defm STQF : Store<"stq", 0b100110, store, QFPRegs, f128>,
|
||||
Requires<[HasV9, HasHardQuad]>;
|
||||
|
||||
// Section B.9 - SETHI Instruction, p. 104
|
||||
def SETHIi: F2_1<0b100,
|
||||
|
154
test/MC/Disassembler/Sparc/sparc-mem.txt
Normal file
154
test/MC/Disassembler/Sparc/sparc-mem.txt
Normal file
@ -0,0 +1,154 @@
|
||||
# RUN: llvm-mc --disassemble %s -triple=sparcv9-unknown-linux | FileCheck %s
|
||||
|
||||
# CHECK: ldsb [%i0+%l6], %o2
|
||||
0xd4 0x4e 0x00 0x16
|
||||
|
||||
# CHECK: ldsb [%i0+32], %o2
|
||||
0xd4 0x4e 0x20 0x20
|
||||
|
||||
# CHECK: ldsb [%g1], %o4
|
||||
0xd8 0x48 0x60 0x00
|
||||
|
||||
# CHECK: ldsh [%i0+%l6], %o2
|
||||
0xd4 0x56 0x00 0x16
|
||||
|
||||
# CHECK: ldsh [%i0+32], %o2
|
||||
0xd4 0x56 0x20 0x20
|
||||
|
||||
# CHECK: ldsh [%g1], %o4
|
||||
0xd8 0x50 0x60 0x00
|
||||
|
||||
# CHECK: ldub [%i0+%l6], %o2
|
||||
0xd4 0x0e 0x00 0x16
|
||||
|
||||
# CHECK: ldub [%i0+32], %o2
|
||||
0xd4 0x0e 0x20 0x20
|
||||
|
||||
# CHECK: ldub [%g1], %o2
|
||||
0xd4 0x08 0x60 0x00
|
||||
|
||||
# CHECK: lduh [%i0+%l6], %o2
|
||||
0xd4 0x16 0x00 0x16
|
||||
|
||||
# CHECK: lduh [%i0+32], %o2
|
||||
0xd4 0x16 0x20 0x20
|
||||
|
||||
# CHECK: lduh [%g1], %o2
|
||||
0xd4 0x10 0x60 0x00
|
||||
|
||||
# CHECK: ld [%i0+%l6], %o2
|
||||
0xd4 0x06 0x00 0x16
|
||||
|
||||
# CHECK: ld [%i0+32], %o2
|
||||
0xd4 0x06 0x20 0x20
|
||||
|
||||
# CHECK: ld [%g1], %o2
|
||||
0xd4 0x00 0x60 0x00
|
||||
|
||||
# CHECK: ld [%i0+%l6], %f2
|
||||
0xc5 0x06 0x00 0x16
|
||||
|
||||
# CHECK: ld [%i0+32], %f2
|
||||
0xc5 0x06 0x20 0x20
|
||||
|
||||
# CHECK: ld [%g1], %f2
|
||||
0xc5 0x00 0x60 0x00
|
||||
|
||||
# CHECK: ldd [%i0+%l6], %f2
|
||||
0xc5 0x1e 0x00 0x16
|
||||
|
||||
# CHECK: ldd [%i0+32], %f2
|
||||
0xc5 0x1e 0x20 0x20
|
||||
|
||||
# CHECK: ldd [%g1], %f2
|
||||
0xc5 0x18 0x60 0x00
|
||||
|
||||
# CHECK: ldq [%i0+%l6], %f4
|
||||
0xc9 0x16 0x00 0x16
|
||||
|
||||
# CHECK: ldq [%i0+32], %f4
|
||||
0xc9 0x16 0x20 0x20
|
||||
|
||||
# CHECK: ldq [%g1], %f4
|
||||
0xc9 0x10 0x60 0x00
|
||||
|
||||
# CHECK: ldx [%i0+%l6], %o2
|
||||
0xd4 0x5e 0x00 0x16
|
||||
|
||||
# CHECK: ldx [%i0+32], %o2
|
||||
0xd4 0x5e 0x20 0x20
|
||||
|
||||
# CHECK: ldx [%g1], %o2
|
||||
0xd4 0x58 0x60 0x00
|
||||
|
||||
# CHECK: ldsw [%i0+%l6], %o2
|
||||
0xd4 0x46 0x00 0x16
|
||||
|
||||
# CHECK: ldsw [%i0+32], %o2
|
||||
0xd4 0x46 0x20 0x20
|
||||
|
||||
# CHECK: ldsw [%g1], %o2
|
||||
0xd4 0x40 0x60 0x00
|
||||
|
||||
# CHECK: stb %o2, [%i0+%l6]
|
||||
0xd4 0x2e 0x00 0x16
|
||||
|
||||
# CHECK: stb %o2, [%i0+32]
|
||||
0xd4 0x2e 0x20 0x20
|
||||
|
||||
# CHECK: stb %o2, [%g1]
|
||||
0xd4 0x28 0x60 0x00
|
||||
|
||||
# CHECK: sth %o2, [%i0+%l6]
|
||||
0xd4 0x36 0x00 0x16
|
||||
|
||||
# CHECK: sth %o2, [%i0+32]
|
||||
0xd4 0x36 0x20 0x20
|
||||
|
||||
# CHECK: sth %o2, [%g1]
|
||||
0xd4 0x30 0x60 0x00
|
||||
|
||||
# CHECK: st %o2, [%i0+%l6]
|
||||
0xd4 0x26 0x00 0x16
|
||||
|
||||
# CHECK: st %o2, [%i0+32]
|
||||
0xd4 0x26 0x20 0x20
|
||||
|
||||
# CHECK: st %o2, [%g1]
|
||||
0xd4 0x20 0x60 0x00
|
||||
|
||||
# CHECK: st %f2, [%i0+%l6]
|
||||
0xc5 0x26 0x00 0x16
|
||||
|
||||
# CHECK: st %f2, [%i0+32]
|
||||
0xc5 0x26 0x20 0x20
|
||||
|
||||
# CHECK: st %f2, [%g1]
|
||||
0xc5 0x20 0x60 0x00
|
||||
|
||||
# CHECK: std %f2, [%i0+%l6]
|
||||
0xc5 0x3e 0x00 0x16
|
||||
|
||||
# CHECK: std %f2, [%i0+32]
|
||||
0xc5 0x3e 0x20 0x20
|
||||
|
||||
# CHECK: std %f2, [%g1]
|
||||
0xc5 0x38 0x60 0x00
|
||||
|
||||
# CHECK: stq %f4, [%i0+%l6]
|
||||
0xc9 0x36 0x00 0x16
|
||||
|
||||
# CHECK: stq %f4, [%i0+32]
|
||||
0xc9 0x36 0x20 0x20
|
||||
|
||||
# CHECK: stq %f4, [%g1]
|
||||
0xc9 0x30 0x60 0x00
|
||||
|
||||
# CHECK: stx %o2, [%i0+%l6]
|
||||
0xd4 0x76 0x00 0x16
|
||||
|
||||
# CHECK: stx %o2, [%i0+32]
|
||||
0xd4 0x76 0x20 0x20
|
||||
|
||||
# CHECK: stx %o2, [%g1]
|
||||
0xd4 0x70 0x60 0x00
|
Loading…
Reference in New Issue
Block a user