Home | History | Annotate | Download | only in Nios2
      1 //===-- Nios2MCInstLower.cpp - Convert Nios2 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 // This file contains code to lower Nios2 MachineInstrs to their corresponding
     11 // MCInst records.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "MCTargetDesc/Nios2BaseInfo.h"
     16 #include "MCTargetDesc/Nios2MCExpr.h"
     17 #include "Nios2.h"
     18 #include "llvm/CodeGen/AsmPrinter.h"
     19 #include "llvm/CodeGen/MachineInstr.h"
     20 #include "llvm/CodeGen/MachineOperand.h"
     21 
     22 using namespace llvm;
     23 
     24 static MCOperand LowerSymbolOperand(const MachineOperand &MO, AsmPrinter &AP) {
     25   MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
     26   Nios2MCExpr::Nios2ExprKind TargetKind = Nios2MCExpr::CEK_None;
     27   const MCSymbol *Symbol;
     28 
     29   switch (MO.getTargetFlags()) {
     30   default:
     31     llvm_unreachable("Invalid target flag!");
     32   case Nios2FG::MO_NO_FLAG:
     33     break;
     34   case Nios2FG::MO_ABS_HI:
     35     TargetKind = Nios2MCExpr::CEK_ABS_HI;
     36     break;
     37   case Nios2FG::MO_ABS_LO:
     38     TargetKind = Nios2MCExpr::CEK_ABS_LO;
     39     break;
     40   }
     41 
     42   switch (MO.getType()) {
     43   case MachineOperand::MO_GlobalAddress:
     44     Symbol = AP.getSymbol(MO.getGlobal());
     45     break;
     46 
     47   case MachineOperand::MO_MachineBasicBlock:
     48     Symbol = MO.getMBB()->getSymbol();
     49     break;
     50 
     51   case MachineOperand::MO_BlockAddress:
     52     Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
     53     break;
     54 
     55   case MachineOperand::MO_ExternalSymbol:
     56     Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
     57     break;
     58 
     59   case MachineOperand::MO_JumpTableIndex:
     60     Symbol = AP.GetJTISymbol(MO.getIndex());
     61     break;
     62 
     63   case MachineOperand::MO_ConstantPoolIndex:
     64     Symbol = AP.GetCPISymbol(MO.getIndex());
     65     break;
     66 
     67   default:
     68     llvm_unreachable("<unknown operand type>");
     69   }
     70 
     71   const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, AP.OutContext);
     72 
     73   if (TargetKind != Nios2MCExpr::CEK_None)
     74     Expr = Nios2MCExpr::create(TargetKind, Expr, AP.OutContext);
     75 
     76   return MCOperand::createExpr(Expr);
     77 }
     78 
     79 static MCOperand LowerOperand(const MachineOperand &MO, AsmPrinter &AP) {
     80 
     81   switch (MO.getType()) {
     82   default:
     83     llvm_unreachable("unknown operand type");
     84   case MachineOperand::MO_Register:
     85     // Ignore all implicit register operands.
     86     if (MO.isImplicit())
     87       break;
     88     return MCOperand::createReg(MO.getReg());
     89   case MachineOperand::MO_Immediate:
     90     return MCOperand::createImm(MO.getImm());
     91   case MachineOperand::MO_MachineBasicBlock:
     92   case MachineOperand::MO_ExternalSymbol:
     93   case MachineOperand::MO_JumpTableIndex:
     94   case MachineOperand::MO_BlockAddress:
     95   case MachineOperand::MO_GlobalAddress:
     96   case MachineOperand::MO_ConstantPoolIndex:
     97     return LowerSymbolOperand(MO, AP);
     98   case MachineOperand::MO_RegisterMask:
     99     break;
    100   }
    101 
    102   return MCOperand();
    103 }
    104 
    105 void llvm::LowerNios2MachineInstToMCInst(const MachineInstr *MI, MCInst &OutMI,
    106                                          AsmPrinter &AP) {
    107 
    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, AP);
    113 
    114     if (MCOp.isValid())
    115       OutMI.addOperand(MCOp);
    116   }
    117 }
    118