xref: /llvm-project/llvm/lib/Target/ARC/ARCMCInstLower.cpp (revision 562356d6e3b5aaceddb4fff34af5fbdcb6748570)
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