1262261Sdim//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===//
2262261Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6262261Sdim//
7262261Sdim//===----------------------------------------------------------------------===//
8262261Sdim//
9262261Sdim// This file contains code to lower Sparc MachineInstrs to their corresponding
10262261Sdim// MCInst records.
11262261Sdim//
12262261Sdim//===----------------------------------------------------------------------===//
13262261Sdim
14321369Sdim#include "MCTargetDesc/SparcMCExpr.h"
15262261Sdim#include "Sparc.h"
16262261Sdim#include "llvm/CodeGen/AsmPrinter.h"
17262261Sdim#include "llvm/CodeGen/MachineFunction.h"
18262261Sdim#include "llvm/CodeGen/MachineInstr.h"
19262261Sdim#include "llvm/CodeGen/MachineOperand.h"
20276479Sdim#include "llvm/IR/Mangler.h"
21276479Sdim#include "llvm/MC/MCAsmInfo.h"
22262261Sdim#include "llvm/MC/MCContext.h"
23262261Sdim#include "llvm/MC/MCExpr.h"
24262261Sdim#include "llvm/MC/MCInst.h"
25262261Sdim
26262261Sdimusing namespace llvm;
27262261Sdim
28262261Sdim
29262261Sdimstatic MCOperand LowerSymbolOperand(const MachineInstr *MI,
30262261Sdim                                    const MachineOperand &MO,
31262261Sdim                                    AsmPrinter &AP) {
32262261Sdim
33262261Sdim  SparcMCExpr::VariantKind Kind =
34262261Sdim    (SparcMCExpr::VariantKind)MO.getTargetFlags();
35276479Sdim  const MCSymbol *Symbol = nullptr;
36262261Sdim
37262261Sdim  switch(MO.getType()) {
38262261Sdim  default: llvm_unreachable("Unknown type in LowerSymbolOperand");
39262261Sdim  case MachineOperand::MO_MachineBasicBlock:
40262261Sdim    Symbol = MO.getMBB()->getSymbol();
41262261Sdim    break;
42262261Sdim
43262261Sdim  case MachineOperand::MO_GlobalAddress:
44262261Sdim    Symbol = AP.getSymbol(MO.getGlobal());
45262261Sdim    break;
46262261Sdim
47262261Sdim  case MachineOperand::MO_BlockAddress:
48262261Sdim    Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
49262261Sdim    break;
50262261Sdim
51262261Sdim  case MachineOperand::MO_ExternalSymbol:
52262261Sdim    Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
53262261Sdim    break;
54262261Sdim
55262261Sdim  case MachineOperand::MO_ConstantPoolIndex:
56262261Sdim    Symbol = AP.GetCPISymbol(MO.getIndex());
57262261Sdim    break;
58262261Sdim  }
59262261Sdim
60288943Sdim  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol,
61262261Sdim                                                         AP.OutContext);
62288943Sdim  const SparcMCExpr *expr = SparcMCExpr::create(Kind, MCSym,
63262261Sdim                                                AP.OutContext);
64288943Sdim  return MCOperand::createExpr(expr);
65262261Sdim}
66262261Sdim
67262261Sdimstatic MCOperand LowerOperand(const MachineInstr *MI,
68262261Sdim                              const MachineOperand &MO,
69262261Sdim                              AsmPrinter &AP) {
70262261Sdim  switch(MO.getType()) {
71262261Sdim  default: llvm_unreachable("unknown operand type"); break;
72262261Sdim  case MachineOperand::MO_Register:
73262261Sdim    if (MO.isImplicit())
74262261Sdim      break;
75288943Sdim    return MCOperand::createReg(MO.getReg());
76262261Sdim
77262261Sdim  case MachineOperand::MO_Immediate:
78288943Sdim    return MCOperand::createImm(MO.getImm());
79262261Sdim
80262261Sdim  case MachineOperand::MO_MachineBasicBlock:
81262261Sdim  case MachineOperand::MO_GlobalAddress:
82262261Sdim  case MachineOperand::MO_BlockAddress:
83262261Sdim  case MachineOperand::MO_ExternalSymbol:
84262261Sdim  case MachineOperand::MO_ConstantPoolIndex:
85262261Sdim    return LowerSymbolOperand(MI, MO, AP);
86262261Sdim
87262261Sdim  case MachineOperand::MO_RegisterMask:   break;
88262261Sdim
89262261Sdim  }
90262261Sdim  return MCOperand();
91262261Sdim}
92262261Sdim
93262261Sdimvoid llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
94262261Sdim                                          MCInst &OutMI,
95262261Sdim                                          AsmPrinter &AP)
96262261Sdim{
97262261Sdim
98262261Sdim  OutMI.setOpcode(MI->getOpcode());
99262261Sdim
100262261Sdim  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
101262261Sdim    const MachineOperand &MO = MI->getOperand(i);
102262261Sdim    MCOperand MCOp = LowerOperand(MI, MO, AP);
103262261Sdim
104262261Sdim    if (MCOp.isValid())
105262261Sdim      OutMI.addOperand(MCOp);
106262261Sdim  }
107262261Sdim}
108