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-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file contains code to lower ARC MachineInstrs to their
11/// 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 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
33 const MCSymbol *Symbol;
34
35 switch (MOTy) {
36 case MachineOperand::MO_MachineBasicBlock:
37 Symbol = MO.getMBB()->getSymbol();
38 break;
39 case MachineOperand::MO_GlobalAddress:
40 Symbol = Printer.getSymbol(GV: MO.getGlobal());
41 Offset += MO.getOffset();
42 break;
43 case MachineOperand::MO_BlockAddress:
44 Symbol = Printer.GetBlockAddressSymbol(BA: MO.getBlockAddress());
45 Offset += MO.getOffset();
46 break;
47 case MachineOperand::MO_ExternalSymbol:
48 Symbol = Printer.GetExternalSymbolSymbol(Sym: MO.getSymbolName());
49 Offset += MO.getOffset();
50 break;
51 case MachineOperand::MO_JumpTableIndex:
52 Symbol = Printer.GetJTISymbol(JTID: MO.getIndex());
53 break;
54 case MachineOperand::MO_ConstantPoolIndex:
55 Symbol = Printer.GetCPISymbol(CPID: MO.getIndex());
56 Offset += MO.getOffset();
57 break;
58 default:
59 llvm_unreachable("<unknown operand type>");
60 }
61
62 assert(Symbol && "Symbol creation failed.\n");
63 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, Ctx&: *Ctx);
64
65 if (!Offset)
66 return MCOperand::createExpr(Val: MCSym);
67
68 // Assume offset is never negative.
69 assert(Offset > 0);
70
71 const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Value: Offset, Ctx&: *Ctx);
72 const MCBinaryExpr *Add = MCBinaryExpr::createAdd(LHS: MCSym, RHS: OffsetExpr, Ctx&: *Ctx);
73 return MCOperand::createExpr(Val: Add);
74}
75
76MCOperand ARCMCInstLower::LowerOperand(const MachineOperand &MO,
77 unsigned Offset) const {
78 MachineOperandType MOTy = MO.getType();
79
80 switch (MOTy) {
81 default:
82 llvm_unreachable("unknown operand type");
83 case MachineOperand::MO_Register:
84 // Ignore all implicit register operands.
85 if (MO.isImplicit())
86 break;
87 return MCOperand::createReg(Reg: MO.getReg());
88 case MachineOperand::MO_Immediate:
89 return MCOperand::createImm(Val: MO.getImm() + Offset);
90 case MachineOperand::MO_MachineBasicBlock:
91 case MachineOperand::MO_GlobalAddress:
92 case MachineOperand::MO_ExternalSymbol:
93 case MachineOperand::MO_JumpTableIndex:
94 case MachineOperand::MO_ConstantPoolIndex:
95 case MachineOperand::MO_BlockAddress:
96 return LowerSymbolOperand(MO, MOTy, Offset);
97 case MachineOperand::MO_RegisterMask:
98 break;
99 }
100
101 return {};
102}
103
104void ARCMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
105 OutMI.setOpcode(MI->getOpcode());
106
107 for (const MachineOperand &MO : MI->operands()) {
108 MCOperand MCOp = LowerOperand(MO);
109
110 if (MCOp.isValid())
111 OutMI.addOperand(Op: MCOp);
112 }
113}
114

source code of llvm/lib/Target/ARC/ARCMCInstLower.cpp