[Sparc] Add support for decoding jmpl/retl/ret instruction.

llvm-svn: 202663
This commit is contained in:
Venkatraman Govindaraju 2014-03-02 21:17:44 +00:00
parent 49c8ae21f5
commit 4fa2ab26f5
4 changed files with 56 additions and 2 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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),

View File

@ -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