Skip to content

Commit a46dd92

Browse files
committed
added evaluateInstruction method. needs tests
1 parent 255870d commit a46dd92

File tree

4 files changed

+67
-15
lines changed

4 files changed

+67
-15
lines changed

llvm/include/llvm/MC/MCInstrAnalysis.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ class MCInstrAnalysis {
181181
evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
182182
uint64_t &Target) const;
183183

184+
virtual bool
185+
evaluateInstruction(const MCInst &Inst, uint64_t Addr, uint64_t Size,
186+
uint64_t &Target) const;
187+
184188
/// Given an instruction tries to get the address of a memory operand. Returns
185189
/// the address on success.
186190
virtual std::optional<uint64_t>

llvm/lib/MC/MCInstrAnalysis.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "llvm/ADT/APInt.h"
1212
#include <cstdint>
13+
#include "MCInstrAnalysis.h"
1314

1415
namespace llvm {
1516
class MCSubtargetInfo;
@@ -30,6 +31,12 @@ bool MCInstrAnalysis::evaluateBranch(const MCInst & /*Inst*/, uint64_t /*Addr*/,
3031
return false;
3132
}
3233

34+
bool llvm::MCInstrAnalysis::evaluateInstruction(const MCInst &Inst,
35+
uint64_t Addr, uint64_t Size,
36+
uint64_t &Target) const {
37+
return false;
38+
}
39+
3340
std::optional<uint64_t> MCInstrAnalysis::evaluateMemoryOperandAddress(
3441
const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
3542
uint64_t Size) const {

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -178,21 +178,24 @@ class RISCVMCInstrAnalysis : public MCInstrAnalysis {
178178
}
179179

180180
switch (Inst.getOpcode()) {
181-
default: {
182-
// Clear the state of all defined registers for instructions that we don't
183-
// explicitly support.
184-
auto NumDefs = Info->get(Inst.getOpcode()).getNumDefs();
185-
for (unsigned I = 0; I < NumDefs; ++I) {
186-
auto DefReg = Inst.getOperand(I).getReg();
187-
if (isGPR(DefReg))
188-
setGPRState(DefReg, std::nullopt);
181+
default: {
182+
// Clear the state of all defined registers for instructions that we don't
183+
// explicitly support.
184+
auto NumDefs = Info->get(Inst.getOpcode()).getNumDefs();
185+
for (unsigned I = 0; I < NumDefs; ++I) {
186+
auto DefReg = Inst.getOperand(I).getReg();
187+
if (isGPR(DefReg))
188+
setGPRState(DefReg, std::nullopt);
189+
}
190+
break;
191+
}
192+
case RISCV::AUIPC:
193+
case RISCV::LUI:
194+
{
195+
setGPRState(Inst.getOperand(0).getReg(),
196+
Inst.getOperand(1).getImm() << 12);
197+
break;
189198
}
190-
break;
191-
}
192-
case RISCV::AUIPC:
193-
setGPRState(Inst.getOperand(0).getReg(),
194-
Addr + (Inst.getOperand(1).getImm() << 12));
195-
break;
196199
}
197200
}
198201

@@ -230,6 +233,44 @@ class RISCVMCInstrAnalysis : public MCInstrAnalysis {
230233
return false;
231234
}
232235

236+
bool evaluateInstruction(const MCInst &Inst, uint64_t Addr, uint64_t Size,
237+
uint64_t &Target) const override {
238+
switch(Inst.getOpcode()) {
239+
default:
240+
return false;
241+
case RISCV::ADDI:
242+
case RISCV::ADDIW: {
243+
if (auto TargetRegState = getGPRState(Inst.getOperand(1).getReg())) {
244+
Target = *TargetRegState + Inst.getOperand(2).getImm();
245+
return true;
246+
}
247+
break;
248+
}
249+
case RISCV::LB:
250+
case RISCV::LH:
251+
case RISCV::LW:
252+
case RISCV::LBU:
253+
case RISCV::LHU:
254+
case RISCV::LWU:
255+
case RISCV::LD:
256+
case RISCV::FLW:
257+
case RISCV::FLD:
258+
case RISCV::SB:
259+
case RISCV::SH:
260+
case RISCV::SW:
261+
case RISCV::FSW:
262+
case RISCV::SD:
263+
case RISCV::FSD: {
264+
int64_t Offset = Inst.getOperand(2).getImm();
265+
if (auto TargetRegState = getGPRState(Inst.getOperand(1).getReg()))
266+
Target = *TargetRegState + Offset;
267+
else
268+
Target = Offset;
269+
return true;
270+
}
271+
}
272+
}
273+
233274
bool isTerminator(const MCInst &Inst) const override {
234275
if (MCInstrAnalysis::isTerminator(Inst))
235276
return true;

llvm/tools/llvm-objdump/llvm-objdump.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1513,7 +1513,7 @@ collectLocalBranchTargets(ArrayRef<uint8_t> Bytes, MCInstrAnalysis *MIA,
15131513
if (MIA) {
15141514
if (Disassembled) {
15151515
uint64_t Target;
1516-
bool TargetKnown = MIA->evaluateBranch(Inst, Index, Size, Target);
1516+
bool TargetKnown = MIA->evaluateBranch(Inst, Index, Size, Target) || MIA->evaluateInstruction(Inst, Index, Size, Target);
15171517
if (TargetKnown && (Target >= Start && Target < End) &&
15181518
!Labels.count(Target)) {
15191519
// On PowerPC and AIX, a function call is encoded as a branch to 0.

0 commit comments

Comments
 (0)