]> git.proxmox.com Git - rustc.git/blame - src/llvm/lib/Target/XCore/XCoreMCInstLower.cpp
Imported Upstream version 1.0.0+dfsg1
[rustc.git] / src / llvm / lib / Target / XCore / XCoreMCInstLower.cpp
CommitLineData
970d7e83
LB
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/// \brief 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"
1a4d82fc 20#include "llvm/IR/Mangler.h"
970d7e83
LB
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCExpr.h"
23#include "llvm/MC/MCInst.h"
970d7e83
LB
24
25using namespace llvm;
26
27XCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter)
28: Printer(asmprinter) {}
29
30void XCoreMCInstLower::Initialize(Mangler *M, MCContext *C) {
31 Mang = M;
32 Ctx = C;
33}
34
35MCOperand XCoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
36 MachineOperandType MOTy,
37 unsigned Offset) const {
38 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
39 const MCSymbol *Symbol;
40
41 switch (MOTy) {
42 case MachineOperand::MO_MachineBasicBlock:
43 Symbol = MO.getMBB()->getSymbol();
44 break;
45 case MachineOperand::MO_GlobalAddress:
1a4d82fc 46 Symbol = Printer.getSymbol(MO.getGlobal());
970d7e83
LB
47 Offset += MO.getOffset();
48 break;
49 case MachineOperand::MO_BlockAddress:
50 Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
51 Offset += MO.getOffset();
52 break;
53 case MachineOperand::MO_ExternalSymbol:
54 Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
55 Offset += MO.getOffset();
56 break;
57 case MachineOperand::MO_JumpTableIndex:
58 Symbol = Printer.GetJTISymbol(MO.getIndex());
59 break;
60 case MachineOperand::MO_ConstantPoolIndex:
61 Symbol = Printer.GetCPISymbol(MO.getIndex());
62 Offset += MO.getOffset();
63 break;
64 default:
65 llvm_unreachable("<unknown operand type>");
66 }
67
68 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx);
69
70 if (!Offset)
71 return MCOperand::CreateExpr(MCSym);
72
73 // Assume offset is never negative.
74 assert(Offset > 0);
75
76 const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, *Ctx);
77 const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx);
78 return MCOperand::CreateExpr(Add);
79}
80
81MCOperand XCoreMCInstLower::LowerOperand(const MachineOperand &MO,
82 unsigned offset) const {
83 MachineOperandType MOTy = MO.getType();
84
85 switch (MOTy) {
86 default: llvm_unreachable("unknown operand type");
87 case MachineOperand::MO_Register:
88 // Ignore all implicit register operands.
89 if (MO.isImplicit()) break;
90 return MCOperand::CreateReg(MO.getReg());
91 case MachineOperand::MO_Immediate:
92 return MCOperand::CreateImm(MO.getImm() + offset);
93 case MachineOperand::MO_MachineBasicBlock:
94 case MachineOperand::MO_GlobalAddress:
95 case MachineOperand::MO_ExternalSymbol:
96 case MachineOperand::MO_JumpTableIndex:
97 case MachineOperand::MO_ConstantPoolIndex:
98 case MachineOperand::MO_BlockAddress:
99 return LowerSymbolOperand(MO, MOTy, offset);
100 case MachineOperand::MO_RegisterMask:
101 break;
102 }
103
104 return MCOperand();
105}
106
107void XCoreMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
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);
113
114 if (MCOp.isValid())
115 OutMI.addOperand(MCOp);
116 }
117}