12d1f6d67SPete Couperus //===- ARCMCInstLower.cpp - ARC MachineInstr to MCInst ----------*- C++ -*-===//
22d1f6d67SPete Couperus //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62d1f6d67SPete Couperus //
72d1f6d67SPete Couperus //===----------------------------------------------------------------------===//
82d1f6d67SPete Couperus ///
92d1f6d67SPete Couperus /// \file
105f8f34e4SAdrian Prantl /// This file contains code to lower ARC MachineInstrs to their
112d1f6d67SPete Couperus /// corresponding MCInst records.
122d1f6d67SPete Couperus ///
132d1f6d67SPete Couperus //===----------------------------------------------------------------------===//
142d1f6d67SPete Couperus
152d1f6d67SPete Couperus #include "ARCMCInstLower.h"
162d1f6d67SPete Couperus #include "llvm/CodeGen/AsmPrinter.h"
172d1f6d67SPete Couperus #include "llvm/CodeGen/MachineFunction.h"
182d1f6d67SPete Couperus #include "llvm/CodeGen/MachineInstr.h"
192d1f6d67SPete Couperus #include "llvm/CodeGen/MachineOperand.h"
202d1f6d67SPete Couperus #include "llvm/MC/MCContext.h"
212d1f6d67SPete Couperus #include "llvm/MC/MCExpr.h"
222d1f6d67SPete Couperus #include "llvm/MC/MCInst.h"
232d1f6d67SPete Couperus
242d1f6d67SPete Couperus using namespace llvm;
252d1f6d67SPete Couperus
ARCMCInstLower(MCContext * C,AsmPrinter & AsmPrinter)262d1f6d67SPete Couperus ARCMCInstLower::ARCMCInstLower(MCContext *C, AsmPrinter &AsmPrinter)
272d1f6d67SPete Couperus : Ctx(C), Printer(AsmPrinter) {}
282d1f6d67SPete Couperus
LowerSymbolOperand(const MachineOperand & MO,MachineOperandType MOTy,unsigned Offset) const292d1f6d67SPete Couperus MCOperand ARCMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
302d1f6d67SPete Couperus MachineOperandType MOTy,
312d1f6d67SPete Couperus unsigned Offset) const {
322d1f6d67SPete Couperus MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
332d1f6d67SPete Couperus const MCSymbol *Symbol;
342d1f6d67SPete Couperus
352d1f6d67SPete Couperus switch (MOTy) {
362d1f6d67SPete Couperus case MachineOperand::MO_MachineBasicBlock:
372d1f6d67SPete Couperus Symbol = MO.getMBB()->getSymbol();
382d1f6d67SPete Couperus break;
392d1f6d67SPete Couperus case MachineOperand::MO_GlobalAddress:
402d1f6d67SPete Couperus Symbol = Printer.getSymbol(MO.getGlobal());
412d1f6d67SPete Couperus Offset += MO.getOffset();
422d1f6d67SPete Couperus break;
432d1f6d67SPete Couperus case MachineOperand::MO_BlockAddress:
442d1f6d67SPete Couperus Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
452d1f6d67SPete Couperus Offset += MO.getOffset();
462d1f6d67SPete Couperus break;
472d1f6d67SPete Couperus case MachineOperand::MO_ExternalSymbol:
482d1f6d67SPete Couperus Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
492d1f6d67SPete Couperus Offset += MO.getOffset();
502d1f6d67SPete Couperus break;
512d1f6d67SPete Couperus case MachineOperand::MO_JumpTableIndex:
522d1f6d67SPete Couperus Symbol = Printer.GetJTISymbol(MO.getIndex());
532d1f6d67SPete Couperus break;
542d1f6d67SPete Couperus case MachineOperand::MO_ConstantPoolIndex:
552d1f6d67SPete Couperus Symbol = Printer.GetCPISymbol(MO.getIndex());
562d1f6d67SPete Couperus Offset += MO.getOffset();
572d1f6d67SPete Couperus break;
582d1f6d67SPete Couperus default:
592d1f6d67SPete Couperus llvm_unreachable("<unknown operand type>");
602d1f6d67SPete Couperus }
612d1f6d67SPete Couperus
622d1f6d67SPete Couperus assert(Symbol && "Symbol creation failed.\n");
632d1f6d67SPete Couperus const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
642d1f6d67SPete Couperus
652d1f6d67SPete Couperus if (!Offset)
662d1f6d67SPete Couperus return MCOperand::createExpr(MCSym);
672d1f6d67SPete Couperus
682d1f6d67SPete Couperus // Assume offset is never negative.
692d1f6d67SPete Couperus assert(Offset > 0);
702d1f6d67SPete Couperus
712d1f6d67SPete Couperus const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx);
722d1f6d67SPete Couperus const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);
732d1f6d67SPete Couperus return MCOperand::createExpr(Add);
742d1f6d67SPete Couperus }
752d1f6d67SPete Couperus
LowerOperand(const MachineOperand & MO,unsigned Offset) const762d1f6d67SPete Couperus MCOperand ARCMCInstLower::LowerOperand(const MachineOperand &MO,
772d1f6d67SPete Couperus unsigned Offset) const {
782d1f6d67SPete Couperus MachineOperandType MOTy = MO.getType();
792d1f6d67SPete Couperus
802d1f6d67SPete Couperus switch (MOTy) {
812d1f6d67SPete Couperus default:
822d1f6d67SPete Couperus llvm_unreachable("unknown operand type");
832d1f6d67SPete Couperus case MachineOperand::MO_Register:
842d1f6d67SPete Couperus // Ignore all implicit register operands.
852d1f6d67SPete Couperus if (MO.isImplicit())
862d1f6d67SPete Couperus break;
872d1f6d67SPete Couperus return MCOperand::createReg(MO.getReg());
882d1f6d67SPete Couperus case MachineOperand::MO_Immediate:
892d1f6d67SPete Couperus return MCOperand::createImm(MO.getImm() + Offset);
902d1f6d67SPete Couperus case MachineOperand::MO_MachineBasicBlock:
912d1f6d67SPete Couperus case MachineOperand::MO_GlobalAddress:
922d1f6d67SPete Couperus case MachineOperand::MO_ExternalSymbol:
932d1f6d67SPete Couperus case MachineOperand::MO_JumpTableIndex:
942d1f6d67SPete Couperus case MachineOperand::MO_ConstantPoolIndex:
952d1f6d67SPete Couperus case MachineOperand::MO_BlockAddress:
962d1f6d67SPete Couperus return LowerSymbolOperand(MO, MOTy, Offset);
972d1f6d67SPete Couperus case MachineOperand::MO_RegisterMask:
982d1f6d67SPete Couperus break;
992d1f6d67SPete Couperus }
1002d1f6d67SPete Couperus
1012d1f6d67SPete Couperus return {};
1022d1f6d67SPete Couperus }
1032d1f6d67SPete Couperus
Lower(const MachineInstr * MI,MCInst & OutMI) const1042d1f6d67SPete Couperus void ARCMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
1052d1f6d67SPete Couperus OutMI.setOpcode(MI->getOpcode());
1062d1f6d67SPete Couperus
107*562356d6SKazu Hirata for (const MachineOperand &MO : MI->operands()) {
1082d1f6d67SPete Couperus MCOperand MCOp = LowerOperand(MO);
1092d1f6d67SPete Couperus
1102d1f6d67SPete Couperus if (MCOp.isValid())
1112d1f6d67SPete Couperus OutMI.addOperand(MCOp);
1122d1f6d67SPete Couperus }
1132d1f6d67SPete Couperus }
114