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