LLVM API Documentation

MBlazeMCInstLower.cpp
Go to the documentation of this file.
00001 //===-- MBlazeMCInstLower.cpp - Convert MBlaze 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 MBlaze MachineInstrs to their corresponding
00011 // MCInst records.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "MBlazeMCInstLower.h"
00016 #include "MBlazeInstrInfo.h"
00017 #include "llvm/ADT/SmallString.h"
00018 #include "llvm/CodeGen/AsmPrinter.h"
00019 #include "llvm/CodeGen/MachineBasicBlock.h"
00020 #include "llvm/CodeGen/MachineInstr.h"
00021 #include "llvm/IR/Constants.h"
00022 #include "llvm/MC/MCAsmInfo.h"
00023 #include "llvm/MC/MCContext.h"
00024 #include "llvm/MC/MCExpr.h"
00025 #include "llvm/MC/MCInst.h"
00026 #include "llvm/Support/Debug.h"
00027 #include "llvm/Support/ErrorHandling.h"
00028 #include "llvm/Support/raw_ostream.h"
00029 #include "llvm/Target/Mangler.h"
00030 using namespace llvm;
00031 
00032 MCSymbol *MBlazeMCInstLower::
00033 GetGlobalAddressSymbol(const MachineOperand &MO) const {
00034   switch (MO.getTargetFlags()) {
00035   default: llvm_unreachable("Unknown target flag on GV operand");
00036   case 0:  break;
00037   }
00038 
00039   return Printer.Mang->getSymbol(MO.getGlobal());
00040 }
00041 
00042 MCSymbol *MBlazeMCInstLower::
00043 GetExternalSymbolSymbol(const MachineOperand &MO) const {
00044   switch (MO.getTargetFlags()) {
00045   default: llvm_unreachable("Unknown target flag on GV operand");
00046   case 0:  break;
00047   }
00048 
00049   return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
00050 }
00051 
00052 MCSymbol *MBlazeMCInstLower::
00053 GetJumpTableSymbol(const MachineOperand &MO) const {
00054   SmallString<256> Name;
00055   raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI"
00056                             << Printer.getFunctionNumber() << '_'
00057                             << MO.getIndex();
00058   switch (MO.getTargetFlags()) {
00059   default: llvm_unreachable("Unknown target flag on GV operand");
00060   case 0:  break;
00061   }
00062 
00063   // Create a symbol for the name.
00064   return Ctx.GetOrCreateSymbol(Name.str());
00065 }
00066 
00067 MCSymbol *MBlazeMCInstLower::
00068 GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
00069   SmallString<256> Name;
00070   raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI"
00071                             << Printer.getFunctionNumber() << '_'
00072                             << MO.getIndex();
00073 
00074   switch (MO.getTargetFlags()) {
00075   default:
00076       llvm_unreachable("Unknown target flag on GV operand");
00077 
00078   case 0: break;
00079   }
00080 
00081   // Create a symbol for the name.
00082   return Ctx.GetOrCreateSymbol(Name.str());
00083 }
00084 
00085 MCSymbol *MBlazeMCInstLower::
00086 GetBlockAddressSymbol(const MachineOperand &MO) const {
00087   switch (MO.getTargetFlags()) {
00088   default: llvm_unreachable("Unknown target flag on GV operand");
00089   case 0: break;
00090   }
00091 
00092   return Printer.GetBlockAddressSymbol(MO.getBlockAddress());
00093 }
00094 
00095 MCOperand MBlazeMCInstLower::
00096 LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
00097   // FIXME: We would like an efficient form for this, so we don't have to do a
00098   // lot of extra uniquing.
00099   const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
00100 
00101   switch (MO.getTargetFlags()) {
00102   default:
00103       llvm_unreachable("Unknown target flag on GV operand");
00104 
00105   case 0: break;
00106   }
00107 
00108   if (!MO.isJTI() && MO.getOffset())
00109     Expr = MCBinaryExpr::CreateAdd(Expr,
00110                                    MCConstantExpr::Create(MO.getOffset(), Ctx),
00111                                    Ctx);
00112   return MCOperand::CreateExpr(Expr);
00113 }
00114 
00115 void MBlazeMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
00116   OutMI.setOpcode(MI->getOpcode());
00117 
00118   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
00119     const MachineOperand &MO = MI->getOperand(i);
00120 
00121     MCOperand MCOp;
00122     switch (MO.getType()) {
00123     default: llvm_unreachable("unknown operand type");
00124     case MachineOperand::MO_Register:
00125       // Ignore all implicit register operands.
00126       if (MO.isImplicit()) continue;
00127       MCOp = MCOperand::CreateReg(MO.getReg());
00128       break;
00129     case MachineOperand::MO_Immediate:
00130       MCOp = MCOperand::CreateImm(MO.getImm());
00131       break;
00132     case MachineOperand::MO_MachineBasicBlock:
00133       MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
00134                          MO.getMBB()->getSymbol(), Ctx));
00135       break;
00136     case MachineOperand::MO_GlobalAddress:
00137       MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
00138       break;
00139     case MachineOperand::MO_ExternalSymbol:
00140       MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
00141       break;
00142     case MachineOperand::MO_JumpTableIndex:
00143       MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
00144       break;
00145     case MachineOperand::MO_ConstantPoolIndex:
00146       MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
00147       break;
00148     case MachineOperand::MO_BlockAddress:
00149       MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
00150       break;
00151     case MachineOperand::MO_FPImmediate: {
00152       bool ignored;
00153       APFloat FVal = MO.getFPImm()->getValueAPF();
00154       FVal.convert(APFloat::IEEEsingle, APFloat::rmTowardZero, &ignored);
00155 
00156       APInt IVal = FVal.bitcastToAPInt();
00157       uint64_t Val = *IVal.getRawData();
00158       MCOp = MCOperand::CreateImm(Val);
00159       break;
00160     }
00161     case MachineOperand::MO_RegisterMask:
00162       continue;
00163     }
00164 
00165     OutMI.addOperand(MCOp);
00166   }
00167 }