xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/ARC/ARCMCInstLower.cpp (revision 4824e7fd18a1223177218d4aec1b3c6c5c4a444e)
10b57cec5SDimitry Andric //===- ARCMCInstLower.cpp - ARC MachineInstr to MCInst ----------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This file contains code to lower ARC MachineInstrs to their
110b57cec5SDimitry Andric /// corresponding MCInst records.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "ARCMCInstLower.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using namespace llvm;
250b57cec5SDimitry Andric 
ARCMCInstLower(MCContext * C,AsmPrinter & AsmPrinter)260b57cec5SDimitry Andric ARCMCInstLower::ARCMCInstLower(MCContext *C, AsmPrinter &AsmPrinter)
270b57cec5SDimitry Andric     : Ctx(C), Printer(AsmPrinter) {}
280b57cec5SDimitry Andric 
LowerSymbolOperand(const MachineOperand & MO,MachineOperandType MOTy,unsigned Offset) const290b57cec5SDimitry Andric MCOperand ARCMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
300b57cec5SDimitry Andric                                              MachineOperandType MOTy,
310b57cec5SDimitry Andric                                              unsigned Offset) const {
320b57cec5SDimitry Andric   MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
330b57cec5SDimitry Andric   const MCSymbol *Symbol;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric   switch (MOTy) {
360b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
370b57cec5SDimitry Andric     Symbol = MO.getMBB()->getSymbol();
380b57cec5SDimitry Andric     break;
390b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
400b57cec5SDimitry Andric     Symbol = Printer.getSymbol(MO.getGlobal());
410b57cec5SDimitry Andric     Offset += MO.getOffset();
420b57cec5SDimitry Andric     break;
430b57cec5SDimitry Andric   case MachineOperand::MO_BlockAddress:
440b57cec5SDimitry Andric     Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
450b57cec5SDimitry Andric     Offset += MO.getOffset();
460b57cec5SDimitry Andric     break;
470b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol:
480b57cec5SDimitry Andric     Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
490b57cec5SDimitry Andric     Offset += MO.getOffset();
500b57cec5SDimitry Andric     break;
510b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
520b57cec5SDimitry Andric     Symbol = Printer.GetJTISymbol(MO.getIndex());
530b57cec5SDimitry Andric     break;
540b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
550b57cec5SDimitry Andric     Symbol = Printer.GetCPISymbol(MO.getIndex());
560b57cec5SDimitry Andric     Offset += MO.getOffset();
570b57cec5SDimitry Andric     break;
580b57cec5SDimitry Andric   default:
590b57cec5SDimitry Andric     llvm_unreachable("<unknown operand type>");
600b57cec5SDimitry Andric   }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   assert(Symbol && "Symbol creation failed.\n");
630b57cec5SDimitry Andric   const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   if (!Offset)
660b57cec5SDimitry Andric     return MCOperand::createExpr(MCSym);
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   // Assume offset is never negative.
690b57cec5SDimitry Andric   assert(Offset > 0);
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx);
720b57cec5SDimitry Andric   const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);
730b57cec5SDimitry Andric   return MCOperand::createExpr(Add);
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric 
LowerOperand(const MachineOperand & MO,unsigned Offset) const760b57cec5SDimitry Andric MCOperand ARCMCInstLower::LowerOperand(const MachineOperand &MO,
770b57cec5SDimitry Andric                                        unsigned Offset) const {
780b57cec5SDimitry Andric   MachineOperandType MOTy = MO.getType();
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   switch (MOTy) {
810b57cec5SDimitry Andric   default:
820b57cec5SDimitry Andric     llvm_unreachable("unknown operand type");
830b57cec5SDimitry Andric   case MachineOperand::MO_Register:
840b57cec5SDimitry Andric     // Ignore all implicit register operands.
850b57cec5SDimitry Andric     if (MO.isImplicit())
860b57cec5SDimitry Andric       break;
870b57cec5SDimitry Andric     return MCOperand::createReg(MO.getReg());
880b57cec5SDimitry Andric   case MachineOperand::MO_Immediate:
890b57cec5SDimitry Andric     return MCOperand::createImm(MO.getImm() + Offset);
900b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
910b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
920b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol:
930b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
940b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
950b57cec5SDimitry Andric   case MachineOperand::MO_BlockAddress:
960b57cec5SDimitry Andric     return LowerSymbolOperand(MO, MOTy, Offset);
970b57cec5SDimitry Andric   case MachineOperand::MO_RegisterMask:
980b57cec5SDimitry Andric     break;
990b57cec5SDimitry Andric   }
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   return {};
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
Lower(const MachineInstr * MI,MCInst & OutMI) const1040b57cec5SDimitry Andric void ARCMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
1050b57cec5SDimitry Andric   OutMI.setOpcode(MI->getOpcode());
1060b57cec5SDimitry Andric 
107*4824e7fdSDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
1080b57cec5SDimitry Andric     MCOperand MCOp = LowerOperand(MO);
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric     if (MCOp.isValid())
1110b57cec5SDimitry Andric       OutMI.addOperand(MCOp);
1120b57cec5SDimitry Andric   }
1130b57cec5SDimitry Andric }
114