diff --git a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index ae07e0b4f74..3c03994e0a9 100644 --- a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -190,6 +190,8 @@ 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); +static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, + uint64_t Address, const void *Decoder); #include "SparcGenDisassemblerTables.inc" @@ -336,3 +338,22 @@ static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, return DecodeMem(Inst, insn, Address, Decoder, false, DecodeQFPRegsRegisterClass); } + +static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, + uint64_t Address, uint64_t Offset, + uint64_t Width, MCInst &MI, + const void *Decoder) { + const MCDisassembler *Dis = static_cast(Decoder); + return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, + Offset, Width); +} + +static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, + uint64_t Address, const void *Decoder) { + unsigned tgt = fieldFromInstruction(insn, 0, 30); + tgt <<= 2; + if (!tryAddingSymbolicOperand(tgt+Address, false, Address, + 0, 30, MI, Decoder)) + MI.addOperand(MCOperand::CreateImm(tgt)); + return MCDisassembler::Success; +} diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 57b692562e4..5744fcea18c 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -106,6 +106,7 @@ def brtarget : Operand { def calltarget : Operand { let EncoderMethod = "getCallTargetOpValue"; + let DecoderMethod = "DecodeCall"; } // Operand for printing out a condition code. @@ -577,8 +578,8 @@ let Uses = [FCC] in // This is the only Format 1 instruction let Uses = [O6], hasDelaySlot = 1, isCall = 1 in { - def CALL : InstSP<(outs), (ins calltarget:$dst, variable_ops), - "call $dst", []> { + def CALL : InstSP<(outs), (ins calltarget:$disp, variable_ops), + "call $disp", []> { bits<30> disp; let op = 1; let Inst{29-0} = disp; diff --git a/test/MC/Disassembler/Sparc/sparc.txt b/test/MC/Disassembler/Sparc/sparc.txt index fefde2c7038..f917c8aa188 100644 --- a/test/MC/Disassembler/Sparc/sparc.txt +++ b/test/MC/Disassembler/Sparc/sparc.txt @@ -170,3 +170,6 @@ # CHECK: restore 0x81 0xe8 0x00 0x00 + +# CHECK: call 16 +0x40 0x00 0x00 0x04