1//===-- XCoreMCInstLower.cpp - Convert XCore MachineInstr to MCInst -------===//
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 XCore MachineInstrs to their
11/// corresponding MCInst records.
12///
13//===----------------------------------------------------------------------===//
14#include "XCoreMCInstLower.h"
15#include "llvm/CodeGen/AsmPrinter.h"
16#include "llvm/CodeGen/MachineFunction.h"
17#include "llvm/CodeGen/MachineInstr.h"
18#include "llvm/CodeGen/MachineOperand.h"
19#include "llvm/IR/Mangler.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
23
24using namespace llvm;
25
26XCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter)
27 : Printer(asmprinter) {}
28
29void XCoreMCInstLower::Initialize(MCContext *C) { Ctx = C; }
30
31MCOperand XCoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
32 MachineOperandType MOTy,
33 unsigned Offset) const {
34 const MCSymbol *Symbol;
35
36 switch (MOTy) {
37 case MachineOperand::MO_MachineBasicBlock:
38 Symbol = MO.getMBB()->getSymbol();
39 break;
40 case MachineOperand::MO_GlobalAddress:
41 Symbol = Printer.getSymbol(GV: MO.getGlobal());
42 Offset += MO.getOffset();
43 break;
44 case MachineOperand::MO_BlockAddress:
45 Symbol = Printer.GetBlockAddressSymbol(BA: MO.getBlockAddress());
46 Offset += MO.getOffset();
47 break;
48 case MachineOperand::MO_ExternalSymbol:
49 Symbol = Printer.GetExternalSymbolSymbol(Sym: MO.getSymbolName());
50 Offset += MO.getOffset();
51 break;
52 case MachineOperand::MO_JumpTableIndex:
53 Symbol = Printer.GetJTISymbol(JTID: MO.getIndex());
54 break;
55 case MachineOperand::MO_ConstantPoolIndex:
56 Symbol = Printer.GetCPISymbol(CPID: MO.getIndex());
57 Offset += MO.getOffset();
58 break;
59 default:
60 llvm_unreachable("<unknown operand type>");
61 }
62
63 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Ctx&: *Ctx);
64 if (!Offset)
65 return MCOperand::createExpr(Val: MCSym);
66
67 // Assume offset is never negative.
68 assert(Offset > 0);
69
70 const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Value: Offset, Ctx&: *Ctx);
71 const MCBinaryExpr *Add = MCBinaryExpr::createAdd(LHS: MCSym, RHS: OffsetExpr, Ctx&: *Ctx);
72 return MCOperand::createExpr(Val: Add);
73}
74
75MCOperand XCoreMCInstLower::LowerOperand(const MachineOperand &MO,
76 unsigned offset) const {
77 MachineOperandType MOTy = MO.getType();
78
79 switch (MOTy) {
80 default: llvm_unreachable("unknown operand type");
81 case MachineOperand::MO_Register:
82 // Ignore all implicit register operands.
83 if (MO.isImplicit()) break;
84 return MCOperand::createReg(Reg: MO.getReg());
85 case MachineOperand::MO_Immediate:
86 return MCOperand::createImm(Val: MO.getImm() + offset);
87 case MachineOperand::MO_MachineBasicBlock:
88 case MachineOperand::MO_GlobalAddress:
89 case MachineOperand::MO_ExternalSymbol:
90 case MachineOperand::MO_JumpTableIndex:
91 case MachineOperand::MO_ConstantPoolIndex:
92 case MachineOperand::MO_BlockAddress:
93 return LowerSymbolOperand(MO, MOTy, Offset: offset);
94 case MachineOperand::MO_RegisterMask:
95 break;
96 }
97
98 return MCOperand();
99}
100
101void XCoreMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
102 OutMI.setOpcode(MI->getOpcode());
103
104 for (const MachineOperand &MO : MI->operands()) {
105 MCOperand MCOp = LowerOperand(MO);
106
107 if (MCOp.isValid())
108 OutMI.addOperand(Op: MCOp);
109 }
110}
111