mirror of
https://github.com/RPCSX/llvm.git
synced 2025-03-04 19:07:26 +00:00
[SystemZ] Call tryAddingSymbolicOperand in the disassembler
Use the tryAddingSymbolicOperand callback to attempt to present immediate values in symbolic form when disassembling. This is currently only used for PC-relative immediates (which are most likely to be symbolic in the SystemZ ISA). Add new DecodeMethod types to allow distinguishing between branch and non-branch instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266469 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8f148cdabd
commit
0f505886f7
@ -46,6 +46,34 @@ extern "C" void LLVMInitializeSystemZDisassembler() {
|
||||
createSystemZDisassembler);
|
||||
}
|
||||
|
||||
/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
|
||||
/// immediate Value in the MCInst.
|
||||
///
|
||||
/// @param Value - The immediate Value, has had any PC adjustment made by
|
||||
/// the caller.
|
||||
/// @param isBranch - If the instruction is a branch instruction
|
||||
/// @param Address - The starting address of the instruction
|
||||
/// @param Offset - The byte offset to this immediate in the instruction
|
||||
/// @param Width - The byte width of this immediate in the instruction
|
||||
///
|
||||
/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
|
||||
/// called then that function is called to get any symbolic information for the
|
||||
/// immediate in the instruction using the Address, Offset and Width. If that
|
||||
/// returns non-zero then the symbolic information it returns is used to create
|
||||
/// an MCExpr and that is added as an operand to the MCInst. If getOpInfo()
|
||||
/// returns zero and isBranch is true then a symbol look up for immediate Value
|
||||
/// is done and if a symbol is found an MCExpr is created with that, else
|
||||
/// an MCExpr with the immediate Value is created. This function returns true
|
||||
/// if it adds an operand to the MCInst and false otherwise.
|
||||
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<const MCDisassembler*>(Decoder);
|
||||
return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
|
||||
Offset, Width);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
const unsigned *Regs, unsigned Size) {
|
||||
assert(RegNo < Size && "Invalid register");
|
||||
@ -206,22 +234,35 @@ static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
|
||||
|
||||
template<unsigned N>
|
||||
static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
|
||||
uint64_t Address) {
|
||||
uint64_t Address,
|
||||
bool isBranch,
|
||||
const void *Decoder) {
|
||||
assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
|
||||
Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) * 2 + Address));
|
||||
uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
|
||||
|
||||
if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
|
||||
Inst, Decoder))
|
||||
Inst.addOperand(MCOperand::createImm(Value));
|
||||
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodePCDBLOperand<16>(Inst, Imm, Address);
|
||||
static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodePCDBLOperand<32>(Inst, Imm, Address);
|
||||
return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
|
||||
|
@ -451,11 +451,11 @@ def PCRelTLS32 : PCRelTLSAsmOperand<"32">;
|
||||
// and multiplied by 2.
|
||||
def brtarget16 : PCRelOperand<OtherVT, PCRel16> {
|
||||
let EncoderMethod = "getPC16DBLEncoding";
|
||||
let DecoderMethod = "decodePC16DBLOperand";
|
||||
let DecoderMethod = "decodePC16DBLBranchOperand";
|
||||
}
|
||||
def brtarget32 : PCRelOperand<OtherVT, PCRel32> {
|
||||
let EncoderMethod = "getPC32DBLEncoding";
|
||||
let DecoderMethod = "decodePC32DBLOperand";
|
||||
let DecoderMethod = "decodePC32DBLBranchOperand";
|
||||
}
|
||||
|
||||
// Variants of brtarget16/32 with an optional additional TLS symbol.
|
||||
@ -464,12 +464,12 @@ def tlssym : Operand<i64> { }
|
||||
def brtarget16tls : PCRelTLSOperand<OtherVT, PCRelTLS16> {
|
||||
let MIOperandInfo = (ops brtarget16:$func, tlssym:$sym);
|
||||
let EncoderMethod = "getPC16DBLTLSEncoding";
|
||||
let DecoderMethod = "decodePC16DBLOperand";
|
||||
let DecoderMethod = "decodePC16DBLBranchOperand";
|
||||
}
|
||||
def brtarget32tls : PCRelTLSOperand<OtherVT, PCRelTLS32> {
|
||||
let MIOperandInfo = (ops brtarget32:$func, tlssym:$sym);
|
||||
let EncoderMethod = "getPC32DBLTLSEncoding";
|
||||
let DecoderMethod = "decodePC32DBLOperand";
|
||||
let DecoderMethod = "decodePC32DBLBranchOperand";
|
||||
}
|
||||
|
||||
// A PC-relative offset of a global value. The offset is sign-extended
|
||||
|
Loading…
x
Reference in New Issue
Block a user