[llvm] r202575 - [Sparc] Add support to disassemble sparc memory instructions.

Venkatraman Govindaraju venkatra at cs.wisc.edu
Fri Feb 28 23:46:34 PST 2014


Author: venkatra
Date: Sat Mar  1 01:46:33 2014
New Revision: 202575

URL: http://llvm.org/viewvc/llvm-project?rev=202575&view=rev
Log:
[Sparc] Add support to disassemble sparc memory instructions.

Added:
    llvm/trunk/test/MC/Disassembler/Sparc/sparc-mem.txt
Modified:
    llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
    llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
    llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td

Modified: llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp?rev=202575&r1=202574&r2=202575&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp Sat Mar  1 01:46:33 2014
@@ -174,6 +174,22 @@ static DecodeStatus DecodeQFPRegsRegiste
   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
 
   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);
+}

Modified: llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td?rev=202575&r1=202574&r2=202575&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td Sat Mar  1 01:46:33 2014
@@ -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)
 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)>;

Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=202575&r1=202574&r2=202575&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Sat Mar  1 01:46:33 2014
@@ -387,28 +387,38 @@ let isReturn = 1, isTerminator = 1, hasD
 }
 
 // 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,

Added: llvm/trunk/test/MC/Disassembler/Sparc/sparc-mem.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Sparc/sparc-mem.txt?rev=202575&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Sparc/sparc-mem.txt (added)
+++ llvm/trunk/test/MC/Disassembler/Sparc/sparc-mem.txt Sat Mar  1 01:46:33 2014
@@ -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





More information about the llvm-commits mailing list