mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	This patch adds support for having the assembler optimize fixups to constructs like "symbol@ha" or "symbol@l" if "symbol" can be resolved at assembler time. This optimization is already present in the PPCMCExpr.cpp code for handling PPC_HA16/PPC_LO16 target expressions. However, those target expression were used only on Darwin targets. This patch changes target expression code so that they are usable also with the GNU assembler (using the @ha / @l syntax instead of the ha16() / lo16() syntax), and changes the MCInst lowering code to generate those target expressions where appropriate. It also changes the asm parser to generate HA16/LO16 target expressions when parsing assembler source that uses the @ha / @l modifiers. The effect is that now the above- mentioned optimization automatically becomes available for those situations too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184436 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			204 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//===-- PPCMCInstLower.cpp - Convert PPC MachineInstr to an MCInst --------===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// This file contains code to lower PPC MachineInstrs to their corresponding
 | 
						|
// MCInst records.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "PPC.h"
 | 
						|
#include "MCTargetDesc/PPCMCExpr.h"
 | 
						|
#include "llvm/ADT/SmallString.h"
 | 
						|
#include "llvm/ADT/Twine.h"
 | 
						|
#include "llvm/CodeGen/AsmPrinter.h"
 | 
						|
#include "llvm/CodeGen/MachineFunction.h"
 | 
						|
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
 | 
						|
#include "llvm/IR/GlobalValue.h"
 | 
						|
#include "llvm/MC/MCAsmInfo.h"
 | 
						|
#include "llvm/MC/MCExpr.h"
 | 
						|
#include "llvm/MC/MCInst.h"
 | 
						|
#include "llvm/Target/Mangler.h"
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) {
 | 
						|
  return AP.MMI->getObjFileInfo<MachineModuleInfoMachO>();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){
 | 
						|
  MCContext &Ctx = AP.OutContext;
 | 
						|
 | 
						|
  SmallString<128> Name;
 | 
						|
  if (!MO.isGlobal()) {
 | 
						|
    assert(MO.isSymbol() && "Isn't a symbol reference");
 | 
						|
    Name += AP.MAI->getGlobalPrefix();
 | 
						|
    Name += MO.getSymbolName();
 | 
						|
  } else {    
 | 
						|
    const GlobalValue *GV = MO.getGlobal();
 | 
						|
    bool isImplicitlyPrivate = false;
 | 
						|
    if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB ||
 | 
						|
        (MO.getTargetFlags() & PPCII::MO_NLP_FLAG))
 | 
						|
      isImplicitlyPrivate = true;
 | 
						|
    
 | 
						|
    AP.Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
 | 
						|
  }
 | 
						|
  
 | 
						|
  // If the target flags on the operand changes the name of the symbol, do that
 | 
						|
  // before we return the symbol.
 | 
						|
  if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB) {
 | 
						|
    Name += "$stub";
 | 
						|
    const char *PGP = AP.MAI->getPrivateGlobalPrefix();
 | 
						|
    const char *Prefix = "";
 | 
						|
    if (!Name.startswith(PGP)) {
 | 
						|
      // http://llvm.org/bugs/show_bug.cgi?id=15763
 | 
						|
      // all stubs and lazy_ptrs should be local symbols, which need leading 'L'
 | 
						|
      Prefix = PGP;
 | 
						|
    }
 | 
						|
    MCSymbol *Sym = Ctx.GetOrCreateSymbol(Twine(Prefix) + Twine(Name));
 | 
						|
    MachineModuleInfoImpl::StubValueTy &StubSym =
 | 
						|
      getMachOMMI(AP).getFnStubEntry(Sym);
 | 
						|
    if (StubSym.getPointer())
 | 
						|
      return Sym;
 | 
						|
    
 | 
						|
    if (MO.isGlobal()) {
 | 
						|
      StubSym =
 | 
						|
      MachineModuleInfoImpl::
 | 
						|
      StubValueTy(AP.Mang->getSymbol(MO.getGlobal()),
 | 
						|
                  !MO.getGlobal()->hasInternalLinkage());
 | 
						|
    } else {
 | 
						|
      Name.erase(Name.end()-5, Name.end());
 | 
						|
      StubSym =
 | 
						|
      MachineModuleInfoImpl::
 | 
						|
      StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false);
 | 
						|
    }
 | 
						|
    return Sym;
 | 
						|
  }
 | 
						|
 | 
						|
  // If the symbol reference is actually to a non_lazy_ptr, not to the symbol,
 | 
						|
  // then add the suffix.
 | 
						|
  if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) {
 | 
						|
    Name += "$non_lazy_ptr";
 | 
						|
    MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
 | 
						|
  
 | 
						|
    MachineModuleInfoMachO &MachO = getMachOMMI(AP);
 | 
						|
    
 | 
						|
    MachineModuleInfoImpl::StubValueTy &StubSym =
 | 
						|
      (MO.getTargetFlags() & PPCII::MO_NLP_HIDDEN_FLAG) ? 
 | 
						|
         MachO.getHiddenGVStubEntry(Sym) : MachO.getGVStubEntry(Sym);
 | 
						|
    
 | 
						|
    if (StubSym.getPointer() == 0) {
 | 
						|
      assert(MO.isGlobal() && "Extern symbol not handled yet");
 | 
						|
      StubSym = MachineModuleInfoImpl::
 | 
						|
                   StubValueTy(AP.Mang->getSymbol(MO.getGlobal()),
 | 
						|
                               !MO.getGlobal()->hasInternalLinkage());
 | 
						|
    }
 | 
						|
    return Sym;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return Ctx.GetOrCreateSymbol(Name.str());
 | 
						|
}
 | 
						|
 | 
						|
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
 | 
						|
                              AsmPrinter &Printer, bool isDarwin) {
 | 
						|
  MCContext &Ctx = Printer.OutContext;
 | 
						|
  MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
 | 
						|
 | 
						|
  unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK;
 | 
						|
 | 
						|
  switch (access) {
 | 
						|
    case PPCII::MO_TPREL16_HA:
 | 
						|
      RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
 | 
						|
      break;
 | 
						|
    case PPCII::MO_TPREL16_LO:
 | 
						|
      RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
 | 
						|
      break;
 | 
						|
    case PPCII::MO_DTPREL16_LO:
 | 
						|
      RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
 | 
						|
      break;
 | 
						|
    case PPCII::MO_TLSLD16_LO:
 | 
						|
      RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO;
 | 
						|
      break;
 | 
						|
    case PPCII::MO_TOC16_LO:
 | 
						|
      RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
 | 
						|
 | 
						|
  if (!MO.isJTI() && MO.getOffset())
 | 
						|
    Expr = MCBinaryExpr::CreateAdd(Expr,
 | 
						|
                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
 | 
						|
                                   Ctx);
 | 
						|
 | 
						|
  // Subtract off the PIC base if required.
 | 
						|
  if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) {
 | 
						|
    const MachineFunction *MF = MO.getParent()->getParent()->getParent();
 | 
						|
    
 | 
						|
    const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx);
 | 
						|
    Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx);
 | 
						|
  }
 | 
						|
 | 
						|
  // Add ha16() / lo16() markers if required.
 | 
						|
  switch (access) {
 | 
						|
    case PPCII::MO_HA16:
 | 
						|
      Expr = PPCMCExpr::CreateHa16(Expr, Ctx);
 | 
						|
      break;
 | 
						|
    case PPCII::MO_LO16:
 | 
						|
      Expr = PPCMCExpr::CreateLo16(Expr, Ctx);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return MCOperand::CreateExpr(Expr);
 | 
						|
}
 | 
						|
 | 
						|
void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
 | 
						|
                                        AsmPrinter &AP, bool isDarwin) {
 | 
						|
  OutMI.setOpcode(MI->getOpcode());
 | 
						|
  
 | 
						|
  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
 | 
						|
    const MachineOperand &MO = MI->getOperand(i);
 | 
						|
    
 | 
						|
    MCOperand MCOp;
 | 
						|
    switch (MO.getType()) {
 | 
						|
    default:
 | 
						|
      MI->dump();
 | 
						|
      llvm_unreachable("unknown operand type");
 | 
						|
    case MachineOperand::MO_Register:
 | 
						|
      assert(!MO.getSubReg() && "Subregs should be eliminated!");
 | 
						|
      MCOp = MCOperand::CreateReg(MO.getReg());
 | 
						|
      break;
 | 
						|
    case MachineOperand::MO_Immediate:
 | 
						|
      MCOp = MCOperand::CreateImm(MO.getImm());
 | 
						|
      break;
 | 
						|
    case MachineOperand::MO_MachineBasicBlock:
 | 
						|
      MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
 | 
						|
                                      MO.getMBB()->getSymbol(), AP.OutContext));
 | 
						|
      break;
 | 
						|
    case MachineOperand::MO_GlobalAddress:
 | 
						|
    case MachineOperand::MO_ExternalSymbol:
 | 
						|
      MCOp = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP, isDarwin);
 | 
						|
      break;
 | 
						|
    case MachineOperand::MO_JumpTableIndex:
 | 
						|
      MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, isDarwin);
 | 
						|
      break;
 | 
						|
    case MachineOperand::MO_ConstantPoolIndex:
 | 
						|
      MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, isDarwin);
 | 
						|
      break;
 | 
						|
    case MachineOperand::MO_BlockAddress:
 | 
						|
      MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP,
 | 
						|
                          isDarwin);
 | 
						|
      break;
 | 
						|
    case MachineOperand::MO_RegisterMask:
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    
 | 
						|
    OutMI.addOperand(MCOp);
 | 
						|
  }
 | 
						|
}
 |