/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- HexagonMCInstLower.cpp - Convert Hexagon MachineInstr to an 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 Hexagon MachineInstrs to their corresponding |
11 | | // MCInst records. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "Hexagon.h" |
16 | | #include "HexagonAsmPrinter.h" |
17 | | #include "MCTargetDesc/HexagonMCExpr.h" |
18 | | #include "MCTargetDesc/HexagonMCInstrInfo.h" |
19 | | #include "MCTargetDesc/HexagonMCTargetDesc.h" |
20 | | #include "llvm/ADT/APFloat.h" |
21 | | #include "llvm/ADT/APInt.h" |
22 | | #include "llvm/CodeGen/MachineBasicBlock.h" |
23 | | #include "llvm/CodeGen/MachineInstr.h" |
24 | | #include "llvm/CodeGen/MachineOperand.h" |
25 | | #include "llvm/IR/Constants.h" |
26 | | #include "llvm/MC/MCContext.h" |
27 | | #include "llvm/MC/MCExpr.h" |
28 | | #include "llvm/MC/MCInst.h" |
29 | | #include "llvm/Support/ErrorHandling.h" |
30 | | #include "llvm/Support/raw_ostream.h" |
31 | | #include <cassert> |
32 | | |
33 | | using namespace llvm; |
34 | | |
35 | | namespace llvm { |
36 | | |
37 | | void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, |
38 | | MCInst &MCB, HexagonAsmPrinter &AP); |
39 | | |
40 | | } // end namespace llvm |
41 | | |
42 | | static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, |
43 | 882 | HexagonAsmPrinter &Printer, bool MustExtend) { |
44 | 882 | MCContext &MC = Printer.OutContext; |
45 | 882 | const MCExpr *ME; |
46 | 882 | |
47 | 882 | // Populate the relocation type based on Hexagon target flags |
48 | 882 | // set on an operand |
49 | 882 | MCSymbolRefExpr::VariantKind RelocationType; |
50 | 882 | switch (MO.getTargetFlags() & ~HexagonII::HMOTF_ConstExtended) { |
51 | 843 | default: |
52 | 843 | RelocationType = MCSymbolRefExpr::VK_None; |
53 | 843 | break; |
54 | 16 | case HexagonII::MO_PCREL: |
55 | 16 | RelocationType = MCSymbolRefExpr::VK_Hexagon_PCREL; |
56 | 16 | break; |
57 | 3 | case HexagonII::MO_GOT: |
58 | 3 | RelocationType = MCSymbolRefExpr::VK_GOT; |
59 | 3 | break; |
60 | 0 | case HexagonII::MO_LO16: |
61 | 0 | RelocationType = MCSymbolRefExpr::VK_Hexagon_LO16; |
62 | 0 | break; |
63 | 0 | case HexagonII::MO_HI16: |
64 | 0 | RelocationType = MCSymbolRefExpr::VK_Hexagon_HI16; |
65 | 0 | break; |
66 | 0 | case HexagonII::MO_GPREL: |
67 | 0 | RelocationType = MCSymbolRefExpr::VK_Hexagon_GPREL; |
68 | 0 | break; |
69 | 6 | case HexagonII::MO_GDGOT: |
70 | 6 | RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_GOT; |
71 | 6 | break; |
72 | 8 | case HexagonII::MO_GDPLT: |
73 | 8 | RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_PLT; |
74 | 8 | break; |
75 | 2 | case HexagonII::MO_IE: |
76 | 2 | RelocationType = MCSymbolRefExpr::VK_Hexagon_IE; |
77 | 2 | break; |
78 | 2 | case HexagonII::MO_IEGOT: |
79 | 2 | RelocationType = MCSymbolRefExpr::VK_Hexagon_IE_GOT; |
80 | 2 | break; |
81 | 2 | case HexagonII::MO_TPREL: |
82 | 2 | RelocationType = MCSymbolRefExpr::VK_TPREL; |
83 | 2 | break; |
84 | 882 | } |
85 | 882 | |
86 | 882 | ME = MCSymbolRefExpr::create(Symbol, RelocationType, MC); |
87 | 882 | |
88 | 882 | if (!MO.isJTI() && 882 MO.getOffset()878 ) |
89 | 272 | ME = MCBinaryExpr::createAdd(ME, MCConstantExpr::create(MO.getOffset(), MC), |
90 | 272 | MC); |
91 | 882 | |
92 | 882 | ME = HexagonMCExpr::create(ME, MC); |
93 | 882 | HexagonMCInstrInfo::setMustExtend(*ME, MustExtend); |
94 | 882 | return MCOperand::createExpr(ME); |
95 | 882 | } |
96 | | |
97 | | // Create an MCInst from a MachineInstr |
98 | | void llvm::HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, |
99 | 22.4k | MCInst &MCB, HexagonAsmPrinter &AP) { |
100 | 22.4k | if (MI->getOpcode() == Hexagon::ENDLOOP022.4k ) { |
101 | 127 | HexagonMCInstrInfo::setInnerLoop(MCB); |
102 | 127 | return; |
103 | 127 | } |
104 | 22.2k | if (22.2k MI->getOpcode() == Hexagon::ENDLOOP122.2k ) { |
105 | 4 | HexagonMCInstrInfo::setOuterLoop(MCB); |
106 | 4 | return; |
107 | 4 | } |
108 | 22.2k | MCInst *MCI = new (AP.OutContext) MCInst; |
109 | 22.2k | MCI->setOpcode(MI->getOpcode()); |
110 | 22.2k | assert(MCI->getOpcode() == static_cast<unsigned>(MI->getOpcode()) && |
111 | 22.2k | "MCI opcode should have been set on construction"); |
112 | 22.2k | |
113 | 99.3k | for (unsigned i = 0, e = MI->getNumOperands(); i < e99.3k ; i++77.1k ) { |
114 | 77.1k | const MachineOperand &MO = MI->getOperand(i); |
115 | 77.1k | MCOperand MCO; |
116 | 77.1k | bool MustExtend = MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended; |
117 | 77.1k | |
118 | 77.1k | switch (MO.getType()) { |
119 | 0 | default: |
120 | 0 | MI->print(errs()); |
121 | 0 | llvm_unreachable("unknown operand type"); |
122 | 242 | case MachineOperand::MO_RegisterMask: |
123 | 242 | continue; |
124 | 63.4k | case MachineOperand::MO_Register: |
125 | 63.4k | // Ignore all implicit register operands. |
126 | 63.4k | if (MO.isImplicit()) |
127 | 24.4k | continue; |
128 | 39.0k | MCO = MCOperand::createReg(MO.getReg()); |
129 | 39.0k | break; |
130 | 0 | case MachineOperand::MO_FPImmediate: { |
131 | 0 | APFloat Val = MO.getFPImm()->getValueAPF(); |
132 | 0 | // FP immediates are used only when setting GPRs, so they may be dealt |
133 | 0 | // with like regular immediates from this point on. |
134 | 0 | auto Expr = HexagonMCExpr::create( |
135 | 0 | MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(), |
136 | 0 | AP.OutContext), |
137 | 0 | AP.OutContext); |
138 | 0 | HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); |
139 | 0 | MCO = MCOperand::createExpr(Expr); |
140 | 0 | break; |
141 | 39.0k | } |
142 | 12.0k | case MachineOperand::MO_Immediate: { |
143 | 12.0k | auto Expr = HexagonMCExpr::create( |
144 | 12.0k | MCConstantExpr::create(MO.getImm(), AP.OutContext), AP.OutContext); |
145 | 12.0k | HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); |
146 | 12.0k | MCO = MCOperand::createExpr(Expr); |
147 | 12.0k | break; |
148 | 39.0k | } |
149 | 480 | case MachineOperand::MO_MachineBasicBlock: { |
150 | 480 | MCExpr const *Expr = MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), |
151 | 480 | AP.OutContext); |
152 | 480 | Expr = HexagonMCExpr::create(Expr, AP.OutContext); |
153 | 480 | HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); |
154 | 480 | MCO = MCOperand::createExpr(Expr); |
155 | 480 | break; |
156 | 39.0k | } |
157 | 803 | case MachineOperand::MO_GlobalAddress: |
158 | 803 | MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP, MustExtend); |
159 | 803 | break; |
160 | 59 | case MachineOperand::MO_ExternalSymbol: |
161 | 59 | MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), |
162 | 59 | AP, MustExtend); |
163 | 59 | break; |
164 | 4 | case MachineOperand::MO_JumpTableIndex: |
165 | 4 | MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, MustExtend); |
166 | 4 | break; |
167 | 15 | case MachineOperand::MO_ConstantPoolIndex: |
168 | 15 | MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, MustExtend); |
169 | 15 | break; |
170 | 1 | case MachineOperand::MO_BlockAddress: |
171 | 1 | MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP, |
172 | 1 | MustExtend); |
173 | 1 | break; |
174 | 52.4k | } |
175 | 52.4k | |
176 | 52.4k | MCI->addOperand(MCO); |
177 | 52.4k | } |
178 | 22.2k | AP.HexagonProcessInstruction(*MCI, *MI); |
179 | 22.2k | HexagonMCInstrInfo::extendIfNeeded(AP.OutContext, MCII, MCB, *MCI); |
180 | 22.2k | MCB.addOperand(MCOperand::createInst(MCI)); |
181 | 22.2k | } |