LLVM API Documentation

ARMMCInstLower.cpp
Go to the documentation of this file.
00001 //===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains code to lower ARM MachineInstrs to their corresponding
00011 // MCInst records.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "ARM.h"
00016 #include "ARMAsmPrinter.h"
00017 #include "MCTargetDesc/ARMBaseInfo.h"
00018 #include "MCTargetDesc/ARMMCExpr.h"
00019 #include "llvm/CodeGen/MachineBasicBlock.h"
00020 #include "llvm/IR/Constants.h"
00021 #include "llvm/IR/Mangler.h"
00022 #include "llvm/MC/MCExpr.h"
00023 #include "llvm/MC/MCInst.h"
00024 using namespace llvm;
00025 
00026 
00027 MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
00028                                       const MCSymbol *Symbol) {
00029   const MCExpr *Expr;
00030   unsigned Option = MO.getTargetFlags() & ARMII::MO_OPTION_MASK;
00031   switch (Option) {
00032   default: {
00033     Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
00034                                    OutContext);
00035     switch (Option) {
00036     default: llvm_unreachable("Unknown target flag on symbol operand");
00037     case ARMII::MO_NO_FLAG:
00038       break;
00039     case ARMII::MO_LO16:
00040       Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
00041                                      OutContext);
00042       Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
00043       break;
00044     case ARMII::MO_HI16:
00045       Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
00046                                      OutContext);
00047       Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
00048       break;
00049     }
00050     break;
00051   }
00052 
00053   case ARMII::MO_PLT:
00054     Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_PLT,
00055                                    OutContext);
00056     break;
00057   }
00058 
00059   if (!MO.isJTI() && MO.getOffset())
00060     Expr = MCBinaryExpr::CreateAdd(Expr,
00061                                    MCConstantExpr::Create(MO.getOffset(),
00062                                                           OutContext),
00063                                    OutContext);
00064   return MCOperand::CreateExpr(Expr);
00065 
00066 }
00067 
00068 bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
00069                                  MCOperand &MCOp) {
00070   switch (MO.getType()) {
00071   default: llvm_unreachable("unknown operand type");
00072   case MachineOperand::MO_Register:
00073     // Ignore all non-CPSR implicit register operands.
00074     if (MO.isImplicit() && MO.getReg() != ARM::CPSR)
00075       return false;
00076     assert(!MO.getSubReg() && "Subregs should be eliminated!");
00077     MCOp = MCOperand::CreateReg(MO.getReg());
00078     break;
00079   case MachineOperand::MO_Immediate:
00080     MCOp = MCOperand::CreateImm(MO.getImm());
00081     break;
00082   case MachineOperand::MO_MachineBasicBlock:
00083     MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
00084         MO.getMBB()->getSymbol(), OutContext));
00085     break;
00086   case MachineOperand::MO_GlobalAddress: {
00087     MCOp = GetSymbolRef(MO,
00088                         GetARMGVSymbol(MO.getGlobal(), MO.getTargetFlags()));
00089     break;
00090   }
00091   case MachineOperand::MO_ExternalSymbol:
00092    MCOp = GetSymbolRef(MO,
00093                         GetExternalSymbolSymbol(MO.getSymbolName()));
00094     break;
00095   case MachineOperand::MO_JumpTableIndex:
00096     MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
00097     break;
00098   case MachineOperand::MO_ConstantPoolIndex:
00099     MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
00100     break;
00101   case MachineOperand::MO_BlockAddress:
00102     MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
00103     break;
00104   case MachineOperand::MO_FPImmediate: {
00105     APFloat Val = MO.getFPImm()->getValueAPF();
00106     bool ignored;
00107     Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
00108     MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
00109     break;
00110   }
00111   case MachineOperand::MO_RegisterMask:
00112     // Ignore call clobbers.
00113     return false;
00114   }
00115   return true;
00116 }
00117 
00118 void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
00119                                         ARMAsmPrinter &AP) {
00120   OutMI.setOpcode(MI->getOpcode());
00121 
00122   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
00123     const MachineOperand &MO = MI->getOperand(i);
00124 
00125     MCOperand MCOp;
00126     if (AP.lowerOperand(MO, MCOp))
00127       OutMI.addOperand(MCOp);
00128   }
00129 }