Home | History | Annotate | Download | only in XCore
      1 //===-- XCoreMCInstLower.cpp - Convert XCore 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 /// \file
     11 /// \brief This file contains code to lower XCore MachineInstrs to their
     12 /// corresponding MCInst records.
     13 ///
     14 //===----------------------------------------------------------------------===//
     15 #include "XCoreMCInstLower.h"
     16 #include "llvm/CodeGen/AsmPrinter.h"
     17 #include "llvm/CodeGen/MachineFunction.h"
     18 #include "llvm/CodeGen/MachineInstr.h"
     19 #include "llvm/CodeGen/MachineOperand.h"
     20 #include "llvm/IR/Mangler.h"
     21 #include "llvm/MC/MCContext.h"
     22 #include "llvm/MC/MCExpr.h"
     23 #include "llvm/MC/MCInst.h"
     24 
     25 using namespace llvm;
     26 
     27 XCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter)
     28 : Printer(asmprinter) {}
     29 
     30 void XCoreMCInstLower::Initialize(Mangler *M, MCContext *C) {
     31   Mang = M;
     32   Ctx = C;
     33 }
     34 
     35 MCOperand XCoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
     36                                                MachineOperandType MOTy,
     37                                                unsigned Offset) const {
     38   MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
     39   const MCSymbol *Symbol;
     40 
     41   switch (MOTy) {
     42     case MachineOperand::MO_MachineBasicBlock:
     43       Symbol = MO.getMBB()->getSymbol();
     44       break;
     45     case MachineOperand::MO_GlobalAddress:
     46       Symbol = Printer.getSymbol(MO.getGlobal());
     47       Offset += MO.getOffset();
     48       break;
     49     case MachineOperand::MO_BlockAddress:
     50       Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
     51       Offset += MO.getOffset();
     52       break;
     53     case MachineOperand::MO_ExternalSymbol:
     54       Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
     55       Offset += MO.getOffset();
     56       break;
     57     case MachineOperand::MO_JumpTableIndex:
     58       Symbol = Printer.GetJTISymbol(MO.getIndex());
     59       break;
     60     case MachineOperand::MO_ConstantPoolIndex:
     61       Symbol = Printer.GetCPISymbol(MO.getIndex());
     62       Offset += MO.getOffset();
     63       break;
     64     default:
     65       llvm_unreachable("<unknown operand type>");
     66   }
     67 
     68   const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx);
     69 
     70   if (!Offset)
     71     return MCOperand::CreateExpr(MCSym);
     72 
     73   // Assume offset is never negative.
     74   assert(Offset > 0);
     75 
     76   const MCConstantExpr *OffsetExpr =  MCConstantExpr::Create(Offset, *Ctx);
     77   const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx);
     78   return MCOperand::CreateExpr(Add);
     79 }
     80 
     81 MCOperand XCoreMCInstLower::LowerOperand(const MachineOperand &MO,
     82                                          unsigned offset) const {
     83   MachineOperandType MOTy = MO.getType();
     84 
     85   switch (MOTy) {
     86     default: llvm_unreachable("unknown operand type");
     87     case MachineOperand::MO_Register:
     88       // Ignore all implicit register operands.
     89       if (MO.isImplicit()) break;
     90       return MCOperand::CreateReg(MO.getReg());
     91     case MachineOperand::MO_Immediate:
     92       return MCOperand::CreateImm(MO.getImm() + offset);
     93     case MachineOperand::MO_MachineBasicBlock:
     94     case MachineOperand::MO_GlobalAddress:
     95     case MachineOperand::MO_ExternalSymbol:
     96     case MachineOperand::MO_JumpTableIndex:
     97     case MachineOperand::MO_ConstantPoolIndex:
     98     case MachineOperand::MO_BlockAddress:
     99       return LowerSymbolOperand(MO, MOTy, offset);
    100     case MachineOperand::MO_RegisterMask:
    101       break;
    102   }
    103 
    104   return MCOperand();
    105 }
    106 
    107 void XCoreMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
    108   OutMI.setOpcode(MI->getOpcode());
    109 
    110   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
    111     const MachineOperand &MO = MI->getOperand(i);
    112     MCOperand MCOp = LowerOperand(MO);
    113 
    114     if (MCOp.isValid())
    115       OutMI.addOperand(MCOp);
    116   }
    117 }
    118