113 lines · cpp
1//===- ARCMCInstLower.cpp - ARC MachineInstr to MCInst ----------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains code to lower ARC MachineInstrs to their11/// corresponding MCInst records.12///13//===----------------------------------------------------------------------===//14 15#include "ARCMCInstLower.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/MC/MCContext.h"21#include "llvm/MC/MCExpr.h"22#include "llvm/MC/MCInst.h"23 24using namespace llvm;25 26ARCMCInstLower::ARCMCInstLower(MCContext *C, AsmPrinter &AsmPrinter)27 : Ctx(C), Printer(AsmPrinter) {}28 29MCOperand ARCMCInstLower::LowerSymbolOperand(const MachineOperand &MO,30 MachineOperandType MOTy,31 unsigned Offset) const {32 const MCSymbol *Symbol;33 34 switch (MOTy) {35 case MachineOperand::MO_MachineBasicBlock:36 Symbol = MO.getMBB()->getSymbol();37 break;38 case MachineOperand::MO_GlobalAddress:39 Symbol = Printer.getSymbol(MO.getGlobal());40 Offset += MO.getOffset();41 break;42 case MachineOperand::MO_BlockAddress:43 Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());44 Offset += MO.getOffset();45 break;46 case MachineOperand::MO_ExternalSymbol:47 Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());48 Offset += MO.getOffset();49 break;50 case MachineOperand::MO_JumpTableIndex:51 Symbol = Printer.GetJTISymbol(MO.getIndex());52 break;53 case MachineOperand::MO_ConstantPoolIndex:54 Symbol = Printer.GetCPISymbol(MO.getIndex());55 Offset += MO.getOffset();56 break;57 default:58 llvm_unreachable("<unknown operand type>");59 }60 61 assert(Symbol && "Symbol creation failed.\n");62 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, *Ctx);63 64 if (!Offset)65 return MCOperand::createExpr(MCSym);66 67 // Assume offset is never negative.68 assert(Offset > 0);69 70 const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx);71 const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);72 return MCOperand::createExpr(Add);73}74 75MCOperand ARCMCInstLower::LowerOperand(const MachineOperand &MO,76 unsigned Offset) const {77 MachineOperandType MOTy = MO.getType();78 79 switch (MOTy) {80 default:81 llvm_unreachable("unknown operand type");82 case MachineOperand::MO_Register:83 // Ignore all implicit register operands.84 if (MO.isImplicit())85 break;86 return MCOperand::createReg(MO.getReg());87 case MachineOperand::MO_Immediate:88 return MCOperand::createImm(MO.getImm() + Offset);89 case MachineOperand::MO_MachineBasicBlock:90 case MachineOperand::MO_GlobalAddress:91 case MachineOperand::MO_ExternalSymbol:92 case MachineOperand::MO_JumpTableIndex:93 case MachineOperand::MO_ConstantPoolIndex:94 case MachineOperand::MO_BlockAddress:95 return LowerSymbolOperand(MO, MOTy, Offset);96 case MachineOperand::MO_RegisterMask:97 break;98 }99 100 return {};101}102 103void ARCMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {104 OutMI.setOpcode(MI->getOpcode());105 106 for (const MachineOperand &MO : MI->operands()) {107 MCOperand MCOp = LowerOperand(MO);108 109 if (MCOp.isValid())110 OutMI.addOperand(MCOp);111 }112}113