]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/XCore/XCoreMCInstLower.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / XCore / XCoreMCInstLower.cpp
1 //===-- XCoreMCInstLower.cpp - Convert XCore 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 /// \file
11 /// This file contains code to lower XCore MachineInstrs to their
12 /// corresponding MCInst records.
13 ///
14 //===----------------------------------------------------------------------===//
15 #include "XCoreMCInstLower.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/IR/Mangler.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24
25 using namespace llvm;
26
27 XCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter)
28     : Printer(asmprinter) {}
29
30 void XCoreMCInstLower::Initialize(MCContext *C) { Ctx = C; }
31
32 MCOperand XCoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
33                                                MachineOperandType MOTy,
34                                                unsigned Offset) const {
35   MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
36   const MCSymbol *Symbol;
37
38   switch (MOTy) {
39     case MachineOperand::MO_MachineBasicBlock:
40       Symbol = MO.getMBB()->getSymbol();
41       break;
42     case MachineOperand::MO_GlobalAddress:
43       Symbol = Printer.getSymbol(MO.getGlobal());
44       Offset += MO.getOffset();
45       break;
46     case MachineOperand::MO_BlockAddress:
47       Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
48       Offset += MO.getOffset();
49       break;
50     case MachineOperand::MO_ExternalSymbol:
51       Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
52       Offset += MO.getOffset();
53       break;
54     case MachineOperand::MO_JumpTableIndex:
55       Symbol = Printer.GetJTISymbol(MO.getIndex());
56       break;
57     case MachineOperand::MO_ConstantPoolIndex:
58       Symbol = Printer.GetCPISymbol(MO.getIndex());
59       Offset += MO.getOffset();
60       break;
61     default:
62       llvm_unreachable("<unknown operand type>");
63   }
64
65   const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
66
67   if (!Offset)
68     return MCOperand::createExpr(MCSym);
69
70   // Assume offset is never negative.
71   assert(Offset > 0);
72
73   const MCConstantExpr *OffsetExpr =  MCConstantExpr::create(Offset, *Ctx);
74   const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);
75   return MCOperand::createExpr(Add);
76 }
77
78 MCOperand XCoreMCInstLower::LowerOperand(const MachineOperand &MO,
79                                          unsigned offset) const {
80   MachineOperandType MOTy = MO.getType();
81
82   switch (MOTy) {
83     default: llvm_unreachable("unknown operand type");
84     case MachineOperand::MO_Register:
85       // Ignore all implicit register operands.
86       if (MO.isImplicit()) break;
87       return MCOperand::createReg(MO.getReg());
88     case MachineOperand::MO_Immediate:
89       return MCOperand::createImm(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 MCOperand();
102 }
103
104 void XCoreMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
105   OutMI.setOpcode(MI->getOpcode());
106
107   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
108     const MachineOperand &MO = MI->getOperand(i);
109     MCOperand MCOp = LowerOperand(MO);
110
111     if (MCOp.isValid())
112       OutMI.addOperand(MCOp);
113   }
114 }