diff options
Diffstat (limited to 'llvm/lib/Target/ARC/ARCMCInstLower.cpp')
-rw-r--r-- | llvm/lib/Target/ARC/ARCMCInstLower.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARC/ARCMCInstLower.cpp b/llvm/lib/Target/ARC/ARCMCInstLower.cpp new file mode 100644 index 00000000000..4658388924e --- /dev/null +++ b/llvm/lib/Target/ARC/ARCMCInstLower.cpp @@ -0,0 +1,115 @@ +//===- ARCMCInstLower.cpp - ARC MachineInstr to MCInst ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file contains code to lower ARC MachineInstrs to their +/// corresponding MCInst records. +/// +//===----------------------------------------------------------------------===// + +#include "ARCMCInstLower.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" + +using namespace llvm; + +ARCMCInstLower::ARCMCInstLower(MCContext *C, AsmPrinter &AsmPrinter) + : Ctx(C), Printer(AsmPrinter) {} + +MCOperand ARCMCInstLower::LowerSymbolOperand(const MachineOperand &MO, + MachineOperandType MOTy, + unsigned Offset) const { + MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; + const MCSymbol *Symbol; + + switch (MOTy) { + case MachineOperand::MO_MachineBasicBlock: + Symbol = MO.getMBB()->getSymbol(); + break; + case MachineOperand::MO_GlobalAddress: + Symbol = Printer.getSymbol(MO.getGlobal()); + Offset += MO.getOffset(); + break; + case MachineOperand::MO_BlockAddress: + Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress()); + Offset += MO.getOffset(); + break; + case MachineOperand::MO_ExternalSymbol: + Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName()); + Offset += MO.getOffset(); + break; + case MachineOperand::MO_JumpTableIndex: + Symbol = Printer.GetJTISymbol(MO.getIndex()); + break; + case MachineOperand::MO_ConstantPoolIndex: + Symbol = Printer.GetCPISymbol(MO.getIndex()); + Offset += MO.getOffset(); + break; + default: + llvm_unreachable("<unknown operand type>"); + } + + assert(Symbol && "Symbol creation failed.\n"); + const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx); + + if (!Offset) + return MCOperand::createExpr(MCSym); + + // Assume offset is never negative. + assert(Offset > 0); + + const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx); + const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx); + return MCOperand::createExpr(Add); +} + +MCOperand ARCMCInstLower::LowerOperand(const MachineOperand &MO, + unsigned Offset) const { + MachineOperandType MOTy = MO.getType(); + + switch (MOTy) { + default: + llvm_unreachable("unknown operand type"); + case MachineOperand::MO_Register: + // Ignore all implicit register operands. + if (MO.isImplicit()) + break; + return MCOperand::createReg(MO.getReg()); + case MachineOperand::MO_Immediate: + return MCOperand::createImm(MO.getImm() + Offset); + case MachineOperand::MO_MachineBasicBlock: + case MachineOperand::MO_GlobalAddress: + case MachineOperand::MO_ExternalSymbol: + case MachineOperand::MO_JumpTableIndex: + case MachineOperand::MO_ConstantPoolIndex: + case MachineOperand::MO_BlockAddress: + return LowerSymbolOperand(MO, MOTy, Offset); + case MachineOperand::MO_RegisterMask: + break; + } + + return {}; +} + +void ARCMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { + OutMI.setOpcode(MI->getOpcode()); + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + MCOperand MCOp = LowerOperand(MO); + + if (MCOp.isValid()) + OutMI.addOperand(MCOp); + } +} |