1b22310fdSJia Liu //===-- MSP430MCInstLower.cpp - Convert MSP430 MachineInstr to an MCInst --===//
2a85a4e21SJim Grosbach //
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
6a85a4e21SJim Grosbach //
7a85a4e21SJim Grosbach //===----------------------------------------------------------------------===//
8a85a4e21SJim Grosbach //
9a85a4e21SJim Grosbach // This file contains code to lower MSP430 MachineInstrs to their corresponding
10a85a4e21SJim Grosbach // MCInst records.
11a85a4e21SJim Grosbach //
12a85a4e21SJim Grosbach //===----------------------------------------------------------------------===//
13a85a4e21SJim Grosbach 
14a85a4e21SJim Grosbach #include "MSP430MCInstLower.h"
15ed0881b2SChandler Carruth #include "llvm/ADT/SmallString.h"
16a85a4e21SJim Grosbach #include "llvm/CodeGen/AsmPrinter.h"
17a85a4e21SJim Grosbach #include "llvm/CodeGen/MachineBasicBlock.h"
18a85a4e21SJim Grosbach #include "llvm/CodeGen/MachineInstr.h"
1958873566SRafael Espindola #include "llvm/IR/DataLayout.h"
20894843cbSRafael Espindola #include "llvm/IR/Mangler.h"
21a85a4e21SJim Grosbach #include "llvm/MC/MCAsmInfo.h"
22a85a4e21SJim Grosbach #include "llvm/MC/MCContext.h"
23a85a4e21SJim Grosbach #include "llvm/MC/MCExpr.h"
24a85a4e21SJim Grosbach #include "llvm/MC/MCInst.h"
25a85a4e21SJim Grosbach #include "llvm/Support/ErrorHandling.h"
26ed0881b2SChandler Carruth #include "llvm/Support/raw_ostream.h"
2758873566SRafael Espindola #include "llvm/Target/TargetMachine.h"
28a85a4e21SJim Grosbach using namespace llvm;
29a85a4e21SJim Grosbach 
30a85a4e21SJim Grosbach MCSymbol *MSP430MCInstLower::
GetGlobalAddressSymbol(const MachineOperand & MO) const31a85a4e21SJim Grosbach GetGlobalAddressSymbol(const MachineOperand &MO) const {
32a85a4e21SJim Grosbach   switch (MO.getTargetFlags()) {
33a85a4e21SJim Grosbach   default: llvm_unreachable("Unknown target flag on GV operand");
34a85a4e21SJim Grosbach   case 0: break;
35a85a4e21SJim Grosbach   }
36a85a4e21SJim Grosbach 
3779858aa3SRafael Espindola   return Printer.getSymbol(MO.getGlobal());
38a85a4e21SJim Grosbach }
39a85a4e21SJim Grosbach 
40a85a4e21SJim Grosbach MCSymbol *MSP430MCInstLower::
GetExternalSymbolSymbol(const MachineOperand & MO) const41a85a4e21SJim Grosbach GetExternalSymbolSymbol(const MachineOperand &MO) const {
42a85a4e21SJim Grosbach   switch (MO.getTargetFlags()) {
43e55c556aSCraig Topper   default: llvm_unreachable("Unknown target flag on GV operand");
44a85a4e21SJim Grosbach   case 0: break;
45a85a4e21SJim Grosbach   }
46a85a4e21SJim Grosbach 
47a85a4e21SJim Grosbach   return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
48a85a4e21SJim Grosbach }
49a85a4e21SJim Grosbach 
50a85a4e21SJim Grosbach MCSymbol *MSP430MCInstLower::
GetJumpTableSymbol(const MachineOperand & MO) const51a85a4e21SJim Grosbach GetJumpTableSymbol(const MachineOperand &MO) const {
52bd7287ebSMehdi Amini   const DataLayout &DL = Printer.getDataLayout();
53a85a4e21SJim Grosbach   SmallString<256> Name;
54bd7287ebSMehdi Amini   raw_svector_ostream(Name) << DL.getPrivateGlobalPrefix() << "JTI"
55a85a4e21SJim Grosbach                             << Printer.getFunctionNumber() << '_'
56a85a4e21SJim Grosbach                             << MO.getIndex();
57a85a4e21SJim Grosbach 
58a85a4e21SJim Grosbach   switch (MO.getTargetFlags()) {
59a85a4e21SJim Grosbach   default: llvm_unreachable("Unknown target flag on GV operand");
60a85a4e21SJim Grosbach   case 0: break;
61a85a4e21SJim Grosbach   }
62a85a4e21SJim Grosbach 
63a85a4e21SJim Grosbach   // Create a symbol for the name.
646f482000SJim Grosbach   return Ctx.getOrCreateSymbol(Name);
65a85a4e21SJim Grosbach }
66a85a4e21SJim Grosbach 
67a85a4e21SJim Grosbach MCSymbol *MSP430MCInstLower::
GetConstantPoolIndexSymbol(const MachineOperand & MO) const68a85a4e21SJim Grosbach GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
69bd7287ebSMehdi Amini   const DataLayout &DL = Printer.getDataLayout();
70a85a4e21SJim Grosbach   SmallString<256> Name;
71bd7287ebSMehdi Amini   raw_svector_ostream(Name) << DL.getPrivateGlobalPrefix() << "CPI"
72a85a4e21SJim Grosbach                             << Printer.getFunctionNumber() << '_'
73a85a4e21SJim Grosbach                             << MO.getIndex();
74a85a4e21SJim Grosbach 
75a85a4e21SJim Grosbach   switch (MO.getTargetFlags()) {
76a85a4e21SJim Grosbach   default: llvm_unreachable("Unknown target flag on GV operand");
77a85a4e21SJim Grosbach   case 0: break;
78a85a4e21SJim Grosbach   }
79a85a4e21SJim Grosbach 
80a85a4e21SJim Grosbach   // Create a symbol for the name.
816f482000SJim Grosbach   return Ctx.getOrCreateSymbol(Name);
82a85a4e21SJim Grosbach }
83a85a4e21SJim Grosbach 
84a85a4e21SJim Grosbach MCSymbol *MSP430MCInstLower::
GetBlockAddressSymbol(const MachineOperand & MO) const85a85a4e21SJim Grosbach GetBlockAddressSymbol(const MachineOperand &MO) const {
86a85a4e21SJim Grosbach   switch (MO.getTargetFlags()) {
87e55c556aSCraig Topper   default: llvm_unreachable("Unknown target flag on GV operand");
88a85a4e21SJim Grosbach   case 0: break;
89a85a4e21SJim Grosbach   }
90a85a4e21SJim Grosbach 
91a85a4e21SJim Grosbach   return Printer.GetBlockAddressSymbol(MO.getBlockAddress());
92a85a4e21SJim Grosbach }
93a85a4e21SJim Grosbach 
94a85a4e21SJim Grosbach MCOperand MSP430MCInstLower::
LowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym) const95a85a4e21SJim Grosbach LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
96a85a4e21SJim Grosbach   // FIXME: We would like an efficient form for this, so we don't have to do a
97a85a4e21SJim Grosbach   // lot of extra uniquing.
9813760bd1SJim Grosbach   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
99a85a4e21SJim Grosbach 
100a85a4e21SJim Grosbach   switch (MO.getTargetFlags()) {
101a85a4e21SJim Grosbach   default: llvm_unreachable("Unknown target flag on GV operand");
102a85a4e21SJim Grosbach   case 0: break;
103a85a4e21SJim Grosbach   }
104a85a4e21SJim Grosbach 
105a85a4e21SJim Grosbach   if (!MO.isJTI() && MO.getOffset())
10613760bd1SJim Grosbach     Expr = MCBinaryExpr::createAdd(Expr,
10713760bd1SJim Grosbach                                    MCConstantExpr::create(MO.getOffset(), Ctx),
108a85a4e21SJim Grosbach                                    Ctx);
109e9119e41SJim Grosbach   return MCOperand::createExpr(Expr);
110a85a4e21SJim Grosbach }
111a85a4e21SJim Grosbach 
11249045c6aSAnton Korobeynikov #define GET_REGINFO_ENUM
11349045c6aSAnton Korobeynikov #include "MSP430GenRegisterInfo.inc"
11449045c6aSAnton Korobeynikov 
Lower(const MachineInstr * MI,MCInst & OutMI) const115a85a4e21SJim Grosbach void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
116a85a4e21SJim Grosbach   OutMI.setOpcode(MI->getOpcode());
117a85a4e21SJim Grosbach 
118*ff649e08SKazu Hirata   for (const MachineOperand &MO : MI->operands()) {
119a85a4e21SJim Grosbach     MCOperand MCOp;
120a85a4e21SJim Grosbach     switch (MO.getType()) {
121a85a4e21SJim Grosbach     default:
1228c209aa8SMatthias Braun       MI->print(errs());
123e55c556aSCraig Topper       llvm_unreachable("unknown operand type");
124a85a4e21SJim Grosbach     case MachineOperand::MO_Register:
125a85a4e21SJim Grosbach       // Ignore all implicit register operands.
126a85a4e21SJim Grosbach       if (MO.isImplicit()) continue;
127e9119e41SJim Grosbach       MCOp = MCOperand::createReg(MO.getReg());
128a85a4e21SJim Grosbach       break;
129a85a4e21SJim Grosbach     case MachineOperand::MO_Immediate:
130e9119e41SJim Grosbach       MCOp = MCOperand::createImm(MO.getImm());
131a85a4e21SJim Grosbach       break;
132a85a4e21SJim Grosbach     case MachineOperand::MO_MachineBasicBlock:
13313760bd1SJim Grosbach       MCOp = MCOperand::createExpr(MCSymbolRefExpr::create(
134a85a4e21SJim Grosbach                          MO.getMBB()->getSymbol(), Ctx));
135a85a4e21SJim Grosbach       break;
136a85a4e21SJim Grosbach     case MachineOperand::MO_GlobalAddress:
137a85a4e21SJim Grosbach       MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
138a85a4e21SJim Grosbach       break;
139a85a4e21SJim Grosbach     case MachineOperand::MO_ExternalSymbol:
140a85a4e21SJim Grosbach       MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
141a85a4e21SJim Grosbach       break;
142a85a4e21SJim Grosbach     case MachineOperand::MO_JumpTableIndex:
143a85a4e21SJim Grosbach       MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
144a85a4e21SJim Grosbach       break;
145a85a4e21SJim Grosbach     case MachineOperand::MO_ConstantPoolIndex:
146a85a4e21SJim Grosbach       MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
147a85a4e21SJim Grosbach       break;
148a85a4e21SJim Grosbach     case MachineOperand::MO_BlockAddress:
149a85a4e21SJim Grosbach       MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
150f1fb1d23SJakob Stoklund Olesen       break;
151f1fb1d23SJakob Stoklund Olesen     case MachineOperand::MO_RegisterMask:
152f1fb1d23SJakob Stoklund Olesen       continue;
153a85a4e21SJim Grosbach     }
154a85a4e21SJim Grosbach 
155a85a4e21SJim Grosbach     OutMI.addOperand(MCOp);
156a85a4e21SJim Grosbach   }
157a85a4e21SJim Grosbach }
158