mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
[Sparc] Add support for decoding jmpl/retl/ret instruction.
llvm-svn: 202663
This commit is contained in:
parent
e3d4c30feb
commit
b64b412386
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user