-
Notifications
You must be signed in to change notification settings - Fork 8
/
EpiphanyMCInstLower.cpp
120 lines (107 loc) · 3.96 KB
/
EpiphanyMCInstLower.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//===-- EpiphanyMCInstLower.cpp - Convert Epiphany MachineInstr to an MCInst -==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains code to lower Epiphany MachineInstrs to their corresponding
// MCInst records.
//
//===----------------------------------------------------------------------===//
#include "EpiphanyAsmPrinter.h"
#include "EpiphanyTargetMachine.h"
#include "MCTargetDesc/EpiphanyMCExpr.h"
#include "Utils/EpiphanyBaseInfo.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Target/Mangler.h"
using namespace llvm;
MCOperand
EpiphanyAsmPrinter::lowerSymbolOperand(const MachineOperand &MO,
const MCSymbol *Sym) const {
const MCExpr *Expr = 0;
Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, OutContext);
switch (MO.getTargetFlags()) {
case EpiphanyII::MO_LO16:
Expr = EpiphanyMCExpr::CreateLo16(Expr, OutContext);
break;
case EpiphanyII::MO_HI16:
Expr = EpiphanyMCExpr::CreateHi16(Expr, OutContext);
break;
case EpiphanyII::MO_NO_FLAG:
// Expr is already correct
break;
default:
llvm_unreachable("Unexpected MachineOperand flag - lowersymboloperand");
}
if (!MO.isJTI() && MO.getOffset())
Expr = MCBinaryExpr::CreateAdd(Expr,
MCConstantExpr::Create(MO.getOffset(),
OutContext),
OutContext);
return MCOperand::CreateExpr(Expr);
}
bool EpiphanyAsmPrinter::lowerOperand(const MachineOperand &MO,
MCOperand &MCOp) const {
switch (MO.getType()) {
default: llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
if (MO.isImplicit())
return false;
assert(!MO.getSubReg() && "Subregs should be eliminated!");
MCOp = MCOperand::CreateReg(MO.getReg());
break;
case MachineOperand::MO_Immediate:
MCOp = MCOperand::CreateImm(MO.getImm());
break;
case MachineOperand::MO_FPImmediate: {// a bit hacky, see arm
APFloat Val = MO.getFPImm()->getValueAPF();
bool ignored;
Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
break;
}
case MachineOperand::MO_BlockAddress:
MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
break;
case MachineOperand::MO_ExternalSymbol:
MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName()));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = lowerSymbolOperand(MO, Mang->getSymbol(MO.getGlobal()));
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
MO.getMBB()->getSymbol(), OutContext));
break;
case MachineOperand::MO_JumpTableIndex:
MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex()));
break;
case MachineOperand::MO_ConstantPoolIndex:
MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex()));
break;
case MachineOperand::MO_RegisterMask:
// Ignore call clobbers
return false;
}
return true;
}
void llvm::LowerEpiphanyMachineInstrToMCInst(const MachineInstr *MI,
MCInst &OutMI,
EpiphanyAsmPrinter &AP) {
OutMI.setOpcode(MI->getOpcode());
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
MCOperand MCOp;
if (AP.lowerOperand(MO, MCOp))
OutMI.addOperand(MCOp);
}
}