summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkatraman Govindaraju <venkatra@cs.wisc.edu>2014-03-02 21:17:44 +0000
committerVenkatraman Govindaraju <venkatra@cs.wisc.edu>2014-03-02 21:17:44 +0000
commitc4b0eecd83dfc70a4e9b9fe433b91ea191199291 (patch)
treeef80b02b7970d9b2395a8d7d1569451e64e21a96
parent3efb8b2c0f95003acfb32b08c3ecc09dcdc9990f (diff)
[Sparc] Add support for decoding jmpl/retl/ret instruction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202663 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Sparc/Disassembler/SparcDisassembler.cpp36
-rw-r--r--lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp10
-rw-r--r--lib/Target/Sparc/SparcInstrInfo.td3
-rw-r--r--test/MC/Disassembler/Sparc/sparc.txt9
4 files changed, 56 insertions, 2 deletions
diff --git a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
index e01196cbccb..ea4d6da3ebe 100644
--- a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+++ b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
@@ -207,6 +207,8 @@ static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address,
+ const void *Decoder);
#include "SparcGenDisassemblerTables.inc"
@@ -379,3 +381,37 @@ static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
MI.addOperand(MCOperand::CreateImm(tgt));
return MCDisassembler::Success;
}
+
+static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
+ const void *Decoder) {
+
+ unsigned rd = fieldFromInstruction(insn, 25, 5);
+ unsigned rs1 = fieldFromInstruction(insn, 14, 5);
+ unsigned 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);
+
+ // Decode RD.
+ DecodeStatus status = DecodeIntRegsRegisterClass(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 RS1 | SIMM13.
+ if (isImm)
+ MI.addOperand(MCOperand::CreateImm(simm13));
+ else {
+ status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
+ if (status != MCDisassembler::Success)
+ return status;
+ }
+ return MCDisassembler::Success;
+}
diff --git a/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp b/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
index 045c99087a4..fabc1252cdf 100644
--- a/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+++ b/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
@@ -61,7 +61,15 @@ bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O)
return false;
switch (MI->getOperand(0).getReg()) {
default: return false;
- case SP::G0: // jmp $addr
+ case SP::G0: // jmp $addr | ret | retl
+ if (MI->getOperand(2).isImm() &&
+ MI->getOperand(2).getImm() == 8) {
+ switch(MI->getOperand(1).getReg()) {
+ default: break;
+ case SP::I7: O << "\tret"; return true;
+ case SP::O7: O << "\tretl"; return true;
+ }
+ }
O << "\tjmp "; printMemOperand(MI, 1, O);
return true;
case SP::O7: // call $addr
diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td
index e8934deeba8..11e3c7467dd 100644
--- a/lib/Target/Sparc/SparcInstrInfo.td
+++ b/lib/Target/Sparc/SparcInstrInfo.td
@@ -385,7 +385,8 @@ let usesCustomInserter = 1, Uses = [FCC0] in {
}
// JMPL Instruction.
-let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in {
+let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
+ DecoderMethod = "DecodeJMPL" in {
def JMPLrr: F3_1<2, 0b111000, (outs IntRegs:$dst), (ins MEMrr:$addr),
"jmpl $addr, $dst", []>;
def JMPLri: F3_2<2, 0b111000, (outs IntRegs:$dst), (ins MEMri:$addr),
diff --git a/test/MC/Disassembler/Sparc/sparc.txt b/test/MC/Disassembler/Sparc/sparc.txt
index 924f65ffce6..289c738800f 100644
--- a/test/MC/Disassembler/Sparc/sparc.txt
+++ b/test/MC/Disassembler/Sparc/sparc.txt
@@ -188,3 +188,12 @@
# CHECK: unimp 12
0x00 0x00 0x00 0x0c
+
+# CHECK: jmp %g1+12
+0x81,0xc0,0x60,0x0c
+
+# CHECK: retl
+0x81 0xc3 0xe0 0x08
+
+# CHECK: ret
+0x81,0xc7,0xe0,0x08