LCOV - code coverage report
Current view: top level - lib/Target/AArch64 - AArch64MCInstLower.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 107 117 91.5 %
Date: 2018-02-23 15:42:53 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //==-- AArch64MCInstLower.cpp - Convert AArch64 MachineInstr to an MCInst --==//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file contains code to lower AArch64 MachineInstrs to their corresponding
      11             : // MCInst records.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "AArch64MCInstLower.h"
      16             : #include "MCTargetDesc/AArch64MCExpr.h"
      17             : #include "Utils/AArch64BaseInfo.h"
      18             : #include "llvm/CodeGen/AsmPrinter.h"
      19             : #include "llvm/CodeGen/MachineBasicBlock.h"
      20             : #include "llvm/CodeGen/MachineInstr.h"
      21             : #include "llvm/CodeGen/TargetLoweringObjectFile.h"
      22             : #include "llvm/IR/Mangler.h"
      23             : #include "llvm/MC/MCContext.h"
      24             : #include "llvm/MC/MCExpr.h"
      25             : #include "llvm/MC/MCInst.h"
      26             : #include "llvm/Support/CodeGen.h"
      27             : #include "llvm/Support/CommandLine.h"
      28             : #include "llvm/Target/TargetMachine.h"
      29             : using namespace llvm;
      30             : 
      31             : extern cl::opt<bool> EnableAArch64ELFLocalDynamicTLSGeneration;
      32             : 
      33        1042 : AArch64MCInstLower::AArch64MCInstLower(MCContext &ctx, AsmPrinter &printer)
      34        2084 :     : Ctx(ctx), Printer(printer) {}
      35             : 
      36             : MCSymbol *
      37        7982 : AArch64MCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
      38        7982 :   const GlobalValue *GV = MO.getGlobal();
      39             :   unsigned TargetFlags = MO.getTargetFlags();
      40        7982 :   const Triple &TheTriple = Printer.TM.getTargetTriple();
      41        7982 :   if (!TheTriple.isOSBinFormatCOFF())
      42        7934 :     return Printer.getSymbol(GV);
      43             : 
      44             :   assert(TheTriple.isOSWindows() &&
      45             :          "Windows is the only supported COFF target");
      46             : 
      47          48 :   bool IsIndirect = (TargetFlags & AArch64II::MO_DLLIMPORT);
      48          48 :   if (!IsIndirect)
      49          30 :     return Printer.getSymbol(GV);
      50             : 
      51             :   SmallString<128> Name;
      52             :   Name = "__imp_";
      53          36 :   Printer.TM.getNameWithPrefix(Name, GV,
      54          18 :                                Printer.getObjFileLowering().getMangler());
      55             : 
      56          36 :   return Ctx.getOrCreateSymbol(Name);
      57             : }
      58             : 
      59             : MCSymbol *
      60         541 : AArch64MCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
      61        1082 :   return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
      62             : }
      63             : 
      64        1339 : MCOperand AArch64MCInstLower::lowerSymbolOperandDarwin(const MachineOperand &MO,
      65             :                                                        MCSymbol *Sym) const {
      66             :   // FIXME: We would like an efficient form for this, so we don't have to do a
      67             :   // lot of extra uniquing.
      68             :   MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
      69        1339 :   if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
      70         362 :     if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      71             :       RefKind = MCSymbolRefExpr::VK_GOTPAGE;
      72         181 :     else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
      73             :              AArch64II::MO_PAGEOFF)
      74             :       RefKind = MCSymbolRefExpr::VK_GOTPAGEOFF;
      75             :     else
      76           0 :       llvm_unreachable("Unexpected target flags with MO_GOT on GV operand");
      77         977 :   } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
      78          44 :     if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      79             :       RefKind = MCSymbolRefExpr::VK_TLVPPAGE;
      80          22 :     else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
      81             :              AArch64II::MO_PAGEOFF)
      82             :       RefKind = MCSymbolRefExpr::VK_TLVPPAGEOFF;
      83             :     else
      84           0 :       llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
      85             :   } else {
      86         933 :     if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      87             :       RefKind = MCSymbolRefExpr::VK_PAGE;
      88         718 :     else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
      89             :              AArch64II::MO_PAGEOFF)
      90             :       RefKind = MCSymbolRefExpr::VK_PAGEOFF;
      91             :   }
      92        1339 :   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
      93        2676 :   if (!MO.isJTI() && MO.getOffset())
      94           0 :     Expr = MCBinaryExpr::createAdd(
      95           0 :         Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
      96        1339 :   return MCOperand::createExpr(Expr);
      97             : }
      98             : 
      99        7458 : MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
     100             :                                                     MCSymbol *Sym) const {
     101             :   uint32_t RefFlags = 0;
     102             : 
     103        7458 :   if (MO.getTargetFlags() & AArch64II::MO_GOT)
     104             :     RefFlags |= AArch64MCExpr::VK_GOT;
     105        7342 :   else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
     106             :     TLSModel::Model Model;
     107         104 :     if (MO.isGlobal()) {
     108          86 :       const GlobalValue *GV = MO.getGlobal();
     109          86 :       Model = Printer.TM.getTLSModel(GV);
     110          86 :       if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
     111             :           Model == TLSModel::LocalDynamic)
     112             :         Model = TLSModel::GeneralDynamic;
     113             : 
     114             :     } else {
     115             :       assert(MO.isSymbol() &&
     116             :              StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
     117             :              "unexpected external TLS symbol");
     118             :       // The general dynamic access sequence is used to get the
     119             :       // address of _TLS_MODULE_BASE_.
     120             :       Model = TLSModel::GeneralDynamic;
     121             :     }
     122          62 :     switch (Model) {
     123           8 :     case TLSModel::InitialExec:
     124             :       RefFlags |= AArch64MCExpr::VK_GOTTPREL;
     125           8 :       break;
     126           8 :     case TLSModel::LocalExec:
     127             :       RefFlags |= AArch64MCExpr::VK_TPREL;
     128           8 :       break;
     129          16 :     case TLSModel::LocalDynamic:
     130             :       RefFlags |= AArch64MCExpr::VK_DTPREL;
     131          16 :       break;
     132             :     case TLSModel::GeneralDynamic:
     133             :       RefFlags |= AArch64MCExpr::VK_TLSDESC;
     134             :       break;
     135             :     }
     136             :   } else {
     137             :     // No modifier means this is a generic reference, classified as absolute for
     138             :     // the cases where it matters (:abs_g0: etc).
     139             :     RefFlags |= AArch64MCExpr::VK_ABS;
     140             :   }
     141             : 
     142        7458 :   if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
     143        2775 :     RefFlags |= AArch64MCExpr::VK_PAGE;
     144        4683 :   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
     145             :            AArch64II::MO_PAGEOFF)
     146        3178 :     RefFlags |= AArch64MCExpr::VK_PAGEOFF;
     147        1505 :   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
     148          31 :     RefFlags |= AArch64MCExpr::VK_G3;
     149        1474 :   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2)
     150          31 :     RefFlags |= AArch64MCExpr::VK_G2;
     151        1443 :   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1)
     152          31 :     RefFlags |= AArch64MCExpr::VK_G1;
     153        1412 :   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
     154          31 :     RefFlags |= AArch64MCExpr::VK_G0;
     155        1381 :   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_HI12)
     156          12 :     RefFlags |= AArch64MCExpr::VK_HI12;
     157             : 
     158        7458 :   if (MO.getTargetFlags() & AArch64II::MO_NC)
     159        3247 :     RefFlags |= AArch64MCExpr::VK_NC;
     160             : 
     161             :   const MCExpr *Expr =
     162        7458 :       MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
     163       14862 :   if (!MO.isJTI() && MO.getOffset())
     164           0 :     Expr = MCBinaryExpr::createAdd(
     165           0 :         Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
     166             : 
     167             :   AArch64MCExpr::VariantKind RefKind;
     168             :   RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
     169        7458 :   Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);
     170             : 
     171        7458 :   return MCOperand::createExpr(Expr);
     172             : }
     173             : 
     174          57 : MCOperand AArch64MCInstLower::lowerSymbolOperandCOFF(const MachineOperand &MO,
     175             :                                                      MCSymbol *Sym) const {
     176             :   MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
     177          57 :   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
     178         114 :   if (!MO.isJTI() && MO.getOffset())
     179           0 :     Expr = MCBinaryExpr::createAdd(
     180           0 :         Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
     181          57 :   return MCOperand::createExpr(Expr);
     182             : }
     183             : 
     184        8854 : MCOperand AArch64MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
     185             :                                                  MCSymbol *Sym) const {
     186        8854 :   if (Printer.TM.getTargetTriple().isOSDarwin())
     187        1339 :     return lowerSymbolOperandDarwin(MO, Sym);
     188        7515 :   if (Printer.TM.getTargetTriple().isOSBinFormatCOFF())
     189          57 :     return lowerSymbolOperandCOFF(MO, Sym);
     190             : 
     191             :   assert(Printer.TM.getTargetTriple().isOSBinFormatELF() && "Invalid target");
     192        7458 :   return lowerSymbolOperandELF(MO, Sym);
     193             : }
     194             : 
     195      215041 : bool AArch64MCInstLower::lowerOperand(const MachineOperand &MO,
     196             :                                       MCOperand &MCOp) const {
     197      215041 :   switch (MO.getType()) {
     198           0 :   default:
     199           0 :     llvm_unreachable("unknown operand type");
     200             :   case MachineOperand::MO_Register:
     201             :     // Ignore all implicit register operands.
     202      164875 :     if (MO.isImplicit())
     203             :       return false;
     204      276130 :     MCOp = MCOperand::createReg(MO.getReg());
     205      138065 :     break;
     206             :   case MachineOperand::MO_RegisterMask:
     207             :     // Regmasks are like implicit defs.
     208             :     return false;
     209       38427 :   case MachineOperand::MO_Immediate:
     210       76854 :     MCOp = MCOperand::createImm(MO.getImm());
     211       38427 :     break;
     212        1295 :   case MachineOperand::MO_MachineBasicBlock:
     213        1295 :     MCOp = MCOperand::createExpr(
     214        1295 :         MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
     215        1295 :     break;
     216        7982 :   case MachineOperand::MO_GlobalAddress:
     217        7982 :     MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
     218        7982 :     break;
     219         541 :   case MachineOperand::MO_ExternalSymbol:
     220         541 :     MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
     221         541 :     break;
     222          31 :   case MachineOperand::MO_MCSymbol:
     223          31 :     MCOp = LowerSymbolOperand(MO, MO.getMCSymbol());
     224          31 :     break;
     225          56 :   case MachineOperand::MO_JumpTableIndex:
     226          56 :     MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
     227          56 :     break;
     228         228 :   case MachineOperand::MO_ConstantPoolIndex:
     229         228 :     MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
     230         228 :     break;
     231          16 :   case MachineOperand::MO_BlockAddress:
     232          16 :     MCOp = LowerSymbolOperand(
     233          16 :         MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
     234          16 :     break;
     235             :   }
     236             :   return true;
     237             : }
     238             : 
     239       68356 : void AArch64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
     240       68356 :   OutMI.setOpcode(MI->getOpcode());
     241             : 
     242      497920 :   for (const MachineOperand &MO : MI->operands()) {
     243             :     MCOperand MCOp;
     244      214782 :     if (lowerOperand(MO, MCOp))
     245             :       OutMI.addOperand(MCOp);
     246             :   }
     247       68356 : }

Generated by: LCOV version 1.13