Home | History | Annotate | Download | only in SystemZ
      1 //===-- SystemZMCInstLower.cpp - Lower MachineInstr to 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 #include "SystemZMCInstLower.h"
     11 #include "SystemZAsmPrinter.h"
     12 #include "llvm/IR/Mangler.h"
     13 #include "llvm/MC/MCExpr.h"
     14 #include "llvm/MC/MCInst.h"
     15 #include "llvm/MC/MCStreamer.h"
     16 
     17 using namespace llvm;
     18 
     19 // Return the VK_* enumeration for MachineOperand target flags Flags.
     20 static MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags) {
     21   switch (Flags & SystemZII::MO_SYMBOL_MODIFIER) {
     22     case 0:
     23       return MCSymbolRefExpr::VK_None;
     24     case SystemZII::MO_GOT:
     25       return MCSymbolRefExpr::VK_GOT;
     26     case SystemZII::MO_INDNTPOFF:
     27       return MCSymbolRefExpr::VK_INDNTPOFF;
     28   }
     29   llvm_unreachable("Unrecognised MO_ACCESS_MODEL");
     30 }
     31 
     32 SystemZMCInstLower::SystemZMCInstLower(MCContext &ctx,
     33                                        SystemZAsmPrinter &asmprinter)
     34   : Ctx(ctx), AsmPrinter(asmprinter) {}
     35 
     36 const MCExpr *
     37 SystemZMCInstLower::getExpr(const MachineOperand &MO,
     38                             MCSymbolRefExpr::VariantKind Kind) const {
     39   const MCSymbol *Symbol;
     40   bool HasOffset = true;
     41   switch (MO.getType()) {
     42   case MachineOperand::MO_MachineBasicBlock:
     43     Symbol = MO.getMBB()->getSymbol();
     44     HasOffset = false;
     45     break;
     46 
     47   case MachineOperand::MO_GlobalAddress:
     48     Symbol = AsmPrinter.getSymbol(MO.getGlobal());
     49     break;
     50 
     51   case MachineOperand::MO_ExternalSymbol:
     52     Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
     53     break;
     54 
     55   case MachineOperand::MO_JumpTableIndex:
     56     Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
     57     HasOffset = false;
     58     break;
     59 
     60   case MachineOperand::MO_ConstantPoolIndex:
     61     Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
     62     break;
     63 
     64   case MachineOperand::MO_BlockAddress:
     65     Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
     66     break;
     67 
     68   default:
     69     llvm_unreachable("unknown operand type");
     70   }
     71   const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, Ctx);
     72   if (HasOffset)
     73     if (int64_t Offset = MO.getOffset()) {
     74       const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
     75       Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx);
     76     }
     77   return Expr;
     78 }
     79 
     80 MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const {
     81   switch (MO.getType()) {
     82   case MachineOperand::MO_Register:
     83     return MCOperand::createReg(MO.getReg());
     84 
     85   case MachineOperand::MO_Immediate:
     86     return MCOperand::createImm(MO.getImm());
     87 
     88   default: {
     89     MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags());
     90     return MCOperand::createExpr(getExpr(MO, Kind));
     91   }
     92   }
     93 }
     94 
     95 void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
     96   OutMI.setOpcode(MI->getOpcode());
     97   for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
     98     const MachineOperand &MO = MI->getOperand(I);
     99     // Ignore all implicit register operands.
    100     if (!MO.isReg() || !MO.isImplicit())
    101       OutMI.addOperand(lowerOperand(MO));
    102   }
    103 }
    104