diff options
author | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2014-03-02 21:17:44 +0000 |
---|---|---|
committer | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2014-03-02 21:17:44 +0000 |
commit | c4b0eecd83dfc70a4e9b9fe433b91ea191199291 (patch) | |
tree | ef80b02b7970d9b2395a8d7d1569451e64e21a96 /lib/Target/Sparc | |
parent | 3efb8b2c0f95003acfb32b08c3ecc09dcdc9990f (diff) | |
download | llvm-c4b0eecd83dfc70a4e9b9fe433b91ea191199291.tar.gz llvm-c4b0eecd83dfc70a4e9b9fe433b91ea191199291.tar.bz2 llvm-c4b0eecd83dfc70a4e9b9fe433b91ea191199291.tar.xz |
[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
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/Disassembler/SparcDisassembler.cpp | 36 | ||||
-rw-r--r-- | lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp | 10 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 3 |
3 files changed, 47 insertions, 2 deletions
diff --git a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index e01196cbcc..ea4d6da3eb 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 045c99087a..fabc1252cd 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 e8934deeba..11e3c7467d 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), |