1 //===-- Nios2MCInstLower.cpp - Convert Nios2 MachineInstr to MCInst -------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains code to lower Nios2 MachineInstrs to their corresponding
11 // MCInst records.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "MCTargetDesc/Nios2BaseInfo.h"
16 #include "MCTargetDesc/Nios2MCExpr.h"
17 #include "Nios2.h"
18 #include "llvm/CodeGen/AsmPrinter.h"
19 #include "llvm/CodeGen/MachineInstr.h"
20 #include "llvm/CodeGen/MachineOperand.h"
21
22 using namespace llvm;
23
LowerSymbolOperand(const MachineOperand & MO,AsmPrinter & AP)24 static MCOperand LowerSymbolOperand(const MachineOperand &MO, AsmPrinter &AP) {
25 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
26 Nios2MCExpr::Nios2ExprKind TargetKind = Nios2MCExpr::CEK_None;
27 const MCSymbol *Symbol;
28
29 switch (MO.getTargetFlags()) {
30 default:
31 llvm_unreachable("Invalid target flag!");
32 case Nios2FG::MO_NO_FLAG:
33 break;
34 case Nios2FG::MO_ABS_HI:
35 TargetKind = Nios2MCExpr::CEK_ABS_HI;
36 break;
37 case Nios2FG::MO_ABS_LO:
38 TargetKind = Nios2MCExpr::CEK_ABS_LO;
39 break;
40 }
41
42 switch (MO.getType()) {
43 case MachineOperand::MO_GlobalAddress:
44 Symbol = AP.getSymbol(MO.getGlobal());
45 break;
46
47 case MachineOperand::MO_MachineBasicBlock:
48 Symbol = MO.getMBB()->getSymbol();
49 break;
50
51 case MachineOperand::MO_BlockAddress:
52 Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
53 break;
54
55 case MachineOperand::MO_ExternalSymbol:
56 Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
57 break;
58
59 case MachineOperand::MO_JumpTableIndex:
60 Symbol = AP.GetJTISymbol(MO.getIndex());
61 break;
62
63 case MachineOperand::MO_ConstantPoolIndex:
64 Symbol = AP.GetCPISymbol(MO.getIndex());
65 break;
66
67 default:
68 llvm_unreachable("<unknown operand type>");
69 }
70
71 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, AP.OutContext);
72
73 if (TargetKind != Nios2MCExpr::CEK_None)
74 Expr = Nios2MCExpr::create(TargetKind, Expr, AP.OutContext);
75
76 return MCOperand::createExpr(Expr);
77 }
78
LowerOperand(const MachineOperand & MO,AsmPrinter & AP)79 static MCOperand LowerOperand(const MachineOperand &MO, AsmPrinter &AP) {
80
81 switch (MO.getType()) {
82 default:
83 llvm_unreachable("unknown operand type");
84 case MachineOperand::MO_Register:
85 // Ignore all implicit register operands.
86 if (MO.isImplicit())
87 break;
88 return MCOperand::createReg(MO.getReg());
89 case MachineOperand::MO_Immediate:
90 return MCOperand::createImm(MO.getImm());
91 case MachineOperand::MO_MachineBasicBlock:
92 case MachineOperand::MO_ExternalSymbol:
93 case MachineOperand::MO_JumpTableIndex:
94 case MachineOperand::MO_BlockAddress:
95 case MachineOperand::MO_GlobalAddress:
96 case MachineOperand::MO_ConstantPoolIndex:
97 return LowerSymbolOperand(MO, AP);
98 case MachineOperand::MO_RegisterMask:
99 break;
100 }
101
102 return MCOperand();
103 }
104
LowerNios2MachineInstToMCInst(const MachineInstr * MI,MCInst & OutMI,AsmPrinter & AP)105 void llvm::LowerNios2MachineInstToMCInst(const MachineInstr *MI, MCInst &OutMI,
106 AsmPrinter &AP) {
107
108 OutMI.setOpcode(MI->getOpcode());
109
110 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
111 const MachineOperand &MO = MI->getOperand(i);
112 MCOperand MCOp = LowerOperand(MO, AP);
113
114 if (MCOp.isValid())
115 OutMI.addOperand(MCOp);
116 }
117 }
118