forked from OSchip/llvm-project
				
			[MC][mips] Add MipsMCInstrAnalysis class and register it as MC instruction analyzer
The `MipsMCInstrAnalysis` class overrides the `evaluateBranch` method and calculates target addresses for branch and calls instructions. That allows llvm-objdump to print functions' names in branch instructions in the disassemble mode. Differential Revision: http://reviews.llvm.org/D18209 llvm-svn: 264309
This commit is contained in:
		
							parent
							
								
									8f42b7b3cd
								
							
						
					
					
						commit
						26fe92d19f
					
				| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
#include "llvm/ADT/Triple.h"
 | 
			
		||||
#include "llvm/MC/MCCodeGenInfo.h"
 | 
			
		||||
#include "llvm/MC/MCELFStreamer.h"
 | 
			
		||||
#include "llvm/MC/MCInstrAnalysis.h"
 | 
			
		||||
#include "llvm/MC/MCInstrInfo.h"
 | 
			
		||||
#include "llvm/MC/MCRegisterInfo.h"
 | 
			
		||||
#include "llvm/MC/MCSubtargetInfo.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -129,6 +130,38 @@ createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
 | 
			
		|||
  return new MipsTargetELFStreamer(S, STI);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
class MipsMCInstrAnalysis : public MCInstrAnalysis {
 | 
			
		||||
public:
 | 
			
		||||
  MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
 | 
			
		||||
 | 
			
		||||
  bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
 | 
			
		||||
                      uint64_t &Target) const override {
 | 
			
		||||
    unsigned NumOps = Inst.getNumOperands();
 | 
			
		||||
    if (NumOps == 0)
 | 
			
		||||
      return false;
 | 
			
		||||
    switch (Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType) {
 | 
			
		||||
    case MCOI::OPERAND_UNKNOWN:
 | 
			
		||||
    case MCOI::OPERAND_IMMEDIATE:
 | 
			
		||||
      // jal, bal ...
 | 
			
		||||
      Target = Inst.getOperand(NumOps - 1).getImm();
 | 
			
		||||
      return true;
 | 
			
		||||
    case MCOI::OPERAND_PCREL:
 | 
			
		||||
      // b, j, beq ...
 | 
			
		||||
      Target = Addr + Inst.getOperand(NumOps - 1).getImm();
 | 
			
		||||
      return true;
 | 
			
		||||
    default:
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MCInstrAnalysis *createMipsMCInstrAnalysis(const MCInstrInfo *Info) {
 | 
			
		||||
  return new MipsMCInstrAnalysis(Info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" void LLVMInitializeMipsTargetMC() {
 | 
			
		||||
  for (Target *T : {&TheMipsTarget, &TheMipselTarget, &TheMips64Target,
 | 
			
		||||
                    &TheMips64elTarget}) {
 | 
			
		||||
| 
						 | 
				
			
			@ -156,6 +189,9 @@ extern "C" void LLVMInitializeMipsTargetMC() {
 | 
			
		|||
    // Register the MC subtarget info.
 | 
			
		||||
    TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
 | 
			
		||||
 | 
			
		||||
    // Register the MC instruction analyzer.
 | 
			
		||||
    TargetRegistry::RegisterMCInstrAnalysis(*T, createMipsMCInstrAnalysis);
 | 
			
		||||
 | 
			
		||||
    // Register the MCInstPrinter.
 | 
			
		||||
    TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o - \
 | 
			
		||||
# RUN:   | llvm-objdump -d - | FileCheck %s
 | 
			
		||||
 | 
			
		||||
# CHECK:      foo:
 | 
			
		||||
# CHECK-NEXT:        0:       0c 00 00 02     jal     8 <loc1>
 | 
			
		||||
# CHECK-NEXT:        4:       00 00 00 00     nop
 | 
			
		||||
#
 | 
			
		||||
# CHECK:      loc1:
 | 
			
		||||
# CHECK-NEXT:        8:       0c 00 00 06     jal     24 <loc3>
 | 
			
		||||
# CHECK-NEXT:        c:       00 00 00 00     nop
 | 
			
		||||
#
 | 
			
		||||
# CHECK:      loc2:
 | 
			
		||||
# CHECK-NEXT:       10:       10 00 ff fd     b       -8 <loc1>
 | 
			
		||||
# CHECK-NEXT:       14:       00 00 00 00     nop
 | 
			
		||||
#
 | 
			
		||||
# CHECK:      loc3:
 | 
			
		||||
# CHECK-NEXT:       18:       10 43 ff fd     beq     $2, $3, -8 <loc2>
 | 
			
		||||
# CHECK-NEXT:       1c:       00 00 00 00     nop
 | 
			
		||||
# CHECK-NEXT:       20:       04 11 ff f9     bal     -24 <loc1>
 | 
			
		||||
# CHECK-NEXT:       24:       00 00 00 00     nop
 | 
			
		||||
# CHECK-NEXT:       28:       08 00 00 04     j       16 <loc2>
 | 
			
		||||
 | 
			
		||||
  .text
 | 
			
		||||
  .globl foo
 | 
			
		||||
  .ent foo
 | 
			
		||||
foo:
 | 
			
		||||
  jal loc1
 | 
			
		||||
loc1:
 | 
			
		||||
  jal loc3
 | 
			
		||||
loc2:
 | 
			
		||||
  b   loc1
 | 
			
		||||
loc3:
 | 
			
		||||
  beq $2, $3, loc2
 | 
			
		||||
  bal loc1
 | 
			
		||||
  j   loc2
 | 
			
		||||
  .end foo
 | 
			
		||||
		Loading…
	
		Reference in New Issue