Bug Summary

File:lib/Target/ARM/ARMAsmPrinter.cpp
Warning:line 371, column 14
The left operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ARMAsmPrinter.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn338205/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/lib/gcc/x86_64-linux-gnu/8/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/lib/Target/ARM -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-07-29-043837-17923-1 -x c++ /build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp -faddrsig

/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp

1//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
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 a printer that converts from our internal representation
11// of machine-dependent LLVM code to GAS-format ARM assembly language.
12//
13//===----------------------------------------------------------------------===//
14
15#include "ARMAsmPrinter.h"
16#include "ARM.h"
17#include "ARMConstantPoolValue.h"
18#include "ARMMachineFunctionInfo.h"
19#include "ARMTargetMachine.h"
20#include "ARMTargetObjectFile.h"
21#include "InstPrinter/ARMInstPrinter.h"
22#include "MCTargetDesc/ARMAddressingModes.h"
23#include "MCTargetDesc/ARMMCExpr.h"
24#include "llvm/ADT/SetVector.h"
25#include "llvm/ADT/SmallString.h"
26#include "llvm/BinaryFormat/COFF.h"
27#include "llvm/CodeGen/MachineFunctionPass.h"
28#include "llvm/CodeGen/MachineJumpTableInfo.h"
29#include "llvm/CodeGen/MachineModuleInfoImpls.h"
30#include "llvm/IR/Constants.h"
31#include "llvm/IR/DataLayout.h"
32#include "llvm/IR/Mangler.h"
33#include "llvm/IR/Module.h"
34#include "llvm/IR/Type.h"
35#include "llvm/MC/MCAsmInfo.h"
36#include "llvm/MC/MCAssembler.h"
37#include "llvm/MC/MCContext.h"
38#include "llvm/MC/MCELFStreamer.h"
39#include "llvm/MC/MCInst.h"
40#include "llvm/MC/MCInstBuilder.h"
41#include "llvm/MC/MCObjectStreamer.h"
42#include "llvm/MC/MCStreamer.h"
43#include "llvm/MC/MCSymbol.h"
44#include "llvm/Support/ARMBuildAttributes.h"
45#include "llvm/Support/Debug.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/TargetParser.h"
48#include "llvm/Support/TargetRegistry.h"
49#include "llvm/Support/raw_ostream.h"
50#include "llvm/Target/TargetMachine.h"
51using namespace llvm;
52
53#define DEBUG_TYPE"asm-printer" "asm-printer"
54
55ARMAsmPrinter::ARMAsmPrinter(TargetMachine &TM,
56 std::unique_ptr<MCStreamer> Streamer)
57 : AsmPrinter(TM, std::move(Streamer)), AFI(nullptr), MCP(nullptr),
58 InConstantPool(false), OptimizationGoals(-1) {}
59
60void ARMAsmPrinter::EmitFunctionBodyEnd() {
61 // Make sure to terminate any constant pools that were at the end
62 // of the function.
63 if (!InConstantPool)
64 return;
65 InConstantPool = false;
66 OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
67}
68
69void ARMAsmPrinter::EmitFunctionEntryLabel() {
70 if (AFI->isThumbFunction()) {
71 OutStreamer->EmitAssemblerFlag(MCAF_Code16);
72 OutStreamer->EmitThumbFunc(CurrentFnSym);
73 } else {
74 OutStreamer->EmitAssemblerFlag(MCAF_Code32);
75 }
76 OutStreamer->EmitLabel(CurrentFnSym);
77}
78
79void ARMAsmPrinter::EmitXXStructor(const DataLayout &DL, const Constant *CV) {
80 uint64_t Size = getDataLayout().getTypeAllocSize(CV->getType());
81 assert(Size && "C++ constructor pointer had zero size!")(static_cast <bool> (Size && "C++ constructor pointer had zero size!"
) ? void (0) : __assert_fail ("Size && \"C++ constructor pointer had zero size!\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 81, __extension__ __PRETTY_FUNCTION__))
;
82
83 const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts());
84 assert(GV && "C++ constructor pointer was not a GlobalValue!")(static_cast <bool> (GV && "C++ constructor pointer was not a GlobalValue!"
) ? void (0) : __assert_fail ("GV && \"C++ constructor pointer was not a GlobalValue!\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 84, __extension__ __PRETTY_FUNCTION__))
;
85
86 const MCExpr *E = MCSymbolRefExpr::create(GetARMGVSymbol(GV,
87 ARMII::MO_NO_FLAG),
88 (Subtarget->isTargetELF()
89 ? MCSymbolRefExpr::VK_ARM_TARGET1
90 : MCSymbolRefExpr::VK_None),
91 OutContext);
92
93 OutStreamer->EmitValue(E, Size);
94}
95
96void ARMAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
97 if (PromotedGlobals.count(GV))
98 // The global was promoted into a constant pool. It should not be emitted.
99 return;
100 AsmPrinter::EmitGlobalVariable(GV);
101}
102
103/// runOnMachineFunction - This uses the EmitInstruction()
104/// method to print assembly for each instruction.
105///
106bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
107 AFI = MF.getInfo<ARMFunctionInfo>();
108 MCP = MF.getConstantPool();
109 Subtarget = &MF.getSubtarget<ARMSubtarget>();
110
111 SetupMachineFunction(MF);
112 const Function &F = MF.getFunction();
113 const TargetMachine& TM = MF.getTarget();
114
115 // Collect all globals that had their storage promoted to a constant pool.
116 // Functions are emitted before variables, so this accumulates promoted
117 // globals from all functions in PromotedGlobals.
118 for (auto *GV : AFI->getGlobalsPromotedToConstantPool())
119 PromotedGlobals.insert(GV);
120
121 // Calculate this function's optimization goal.
122 unsigned OptimizationGoal;
123 if (F.hasFnAttribute(Attribute::OptimizeNone))
124 // For best debugging illusion, speed and small size sacrificed
125 OptimizationGoal = 6;
126 else if (F.optForMinSize())
127 // Aggressively for small size, speed and debug illusion sacrificed
128 OptimizationGoal = 4;
129 else if (F.optForSize())
130 // For small size, but speed and debugging illusion preserved
131 OptimizationGoal = 3;
132 else if (TM.getOptLevel() == CodeGenOpt::Aggressive)
133 // Aggressively for speed, small size and debug illusion sacrificed
134 OptimizationGoal = 2;
135 else if (TM.getOptLevel() > CodeGenOpt::None)
136 // For speed, but small size and good debug illusion preserved
137 OptimizationGoal = 1;
138 else // TM.getOptLevel() == CodeGenOpt::None
139 // For good debugging, but speed and small size preserved
140 OptimizationGoal = 5;
141
142 // Combine a new optimization goal with existing ones.
143 if (OptimizationGoals == -1) // uninitialized goals
144 OptimizationGoals = OptimizationGoal;
145 else if (OptimizationGoals != (int)OptimizationGoal) // conflicting goals
146 OptimizationGoals = 0;
147
148 if (Subtarget->isTargetCOFF()) {
149 bool Internal = F.hasInternalLinkage();
150 COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC
151 : COFF::IMAGE_SYM_CLASS_EXTERNAL;
152 int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
153
154 OutStreamer->BeginCOFFSymbolDef(CurrentFnSym);
155 OutStreamer->EmitCOFFSymbolStorageClass(Scl);
156 OutStreamer->EmitCOFFSymbolType(Type);
157 OutStreamer->EndCOFFSymbolDef();
158 }
159
160 // Emit the rest of the function body.
161 EmitFunctionBody();
162
163 // Emit the XRay table for this function.
164 emitXRayTable();
165
166 // If we need V4T thumb mode Register Indirect Jump pads, emit them.
167 // These are created per function, rather than per TU, since it's
168 // relatively easy to exceed the thumb branch range within a TU.
169 if (! ThumbIndirectPads.empty()) {
170 OutStreamer->EmitAssemblerFlag(MCAF_Code16);
171 EmitAlignment(1);
172 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
173 OutStreamer->EmitLabel(TIP.second);
174 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tBX)
175 .addReg(TIP.first)
176 // Add predicate operands.
177 .addImm(ARMCC::AL)
178 .addReg(0));
179 }
180 ThumbIndirectPads.clear();
181 }
182
183 // We didn't modify anything.
184 return false;
185}
186
187void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
188 raw_ostream &O) {
189 const MachineOperand &MO = MI->getOperand(OpNum);
190 unsigned TF = MO.getTargetFlags();
191
192 switch (MO.getType()) {
193 default: llvm_unreachable("<unknown operand type>")::llvm::llvm_unreachable_internal("<unknown operand type>"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 193)
;
194 case MachineOperand::MO_Register: {
195 unsigned Reg = MO.getReg();
196 assert(TargetRegisterInfo::isPhysicalRegister(Reg))(static_cast <bool> (TargetRegisterInfo::isPhysicalRegister
(Reg)) ? void (0) : __assert_fail ("TargetRegisterInfo::isPhysicalRegister(Reg)"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 196, __extension__ __PRETTY_FUNCTION__))
;
197 assert(!MO.getSubReg() && "Subregs should be eliminated!")(static_cast <bool> (!MO.getSubReg() && "Subregs should be eliminated!"
) ? void (0) : __assert_fail ("!MO.getSubReg() && \"Subregs should be eliminated!\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 197, __extension__ __PRETTY_FUNCTION__))
;
198 if(ARM::GPRPairRegClass.contains(Reg)) {
199 const MachineFunction &MF = *MI->getParent()->getParent();
200 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
201 Reg = TRI->getSubReg(Reg, ARM::gsub_0);
202 }
203 O << ARMInstPrinter::getRegisterName(Reg);
204 break;
205 }
206 case MachineOperand::MO_Immediate: {
207 int64_t Imm = MO.getImm();
208 O << '#';
209 if (TF == ARMII::MO_LO16)
210 O << ":lower16:";
211 else if (TF == ARMII::MO_HI16)
212 O << ":upper16:";
213 O << Imm;
214 break;
215 }
216 case MachineOperand::MO_MachineBasicBlock:
217 MO.getMBB()->getSymbol()->print(O, MAI);
218 return;
219 case MachineOperand::MO_GlobalAddress: {
220 const GlobalValue *GV = MO.getGlobal();
221 if (TF & ARMII::MO_LO16)
222 O << ":lower16:";
223 else if (TF & ARMII::MO_HI16)
224 O << ":upper16:";
225 GetARMGVSymbol(GV, TF)->print(O, MAI);
226
227 printOffset(MO.getOffset(), O);
228 break;
229 }
230 case MachineOperand::MO_ConstantPoolIndex:
231 if (Subtarget->genExecuteOnly())
232 llvm_unreachable("execute-only should not generate constant pools")::llvm::llvm_unreachable_internal("execute-only should not generate constant pools"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 232)
;
233 GetCPISymbol(MO.getIndex())->print(O, MAI);
234 break;
235 }
236}
237
238MCSymbol *ARMAsmPrinter::GetCPISymbol(unsigned CPID) const {
239 // The AsmPrinter::GetCPISymbol superclass method tries to use CPID as
240 // indexes in MachineConstantPool, which isn't in sync with indexes used here.
241 const DataLayout &DL = getDataLayout();
242 return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
243 "CPI" + Twine(getFunctionNumber()) + "_" +
244 Twine(CPID));
245}
246
247//===--------------------------------------------------------------------===//
248
249MCSymbol *ARMAsmPrinter::
250GetARMJTIPICJumpTableLabel(unsigned uid) const {
251 const DataLayout &DL = getDataLayout();
252 SmallString<60> Name;
253 raw_svector_ostream(Name) << DL.getPrivateGlobalPrefix() << "JTI"
254 << getFunctionNumber() << '_' << uid;
255 return OutContext.getOrCreateSymbol(Name);
256}
257
258bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
259 unsigned AsmVariant, const char *ExtraCode,
260 raw_ostream &O) {
261 // Does this asm operand have a single letter operand modifier?
262 if (ExtraCode && ExtraCode[0]) {
1
Assuming 'ExtraCode' is non-null
2
Assuming the condition is true
3
Taking true branch
263 if (ExtraCode[1] != 0) return true; // Unknown modifier.
4
Assuming the condition is false
5
Taking false branch
264
265 switch (ExtraCode[0]) {
6
Control jumps to 'case 81:' at line 344
266 default:
267 // See if this is a generic print operand
268 return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O);
269 case 'a': // Print as a memory address.
270 if (MI->getOperand(OpNum).isReg()) {
271 O << "["
272 << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
273 << "]";
274 return false;
275 }
276 LLVM_FALLTHROUGH[[clang::fallthrough]];
277 case 'c': // Don't print "#" before an immediate operand.
278 if (!MI->getOperand(OpNum).isImm())
279 return true;
280 O << MI->getOperand(OpNum).getImm();
281 return false;
282 case 'P': // Print a VFP double precision register.
283 case 'q': // Print a NEON quad precision register.
284 printOperand(MI, OpNum, O);
285 return false;
286 case 'y': // Print a VFP single precision register as indexed double.
287 if (MI->getOperand(OpNum).isReg()) {
288 unsigned Reg = MI->getOperand(OpNum).getReg();
289 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
290 // Find the 'd' register that has this 's' register as a sub-register,
291 // and determine the lane number.
292 for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) {
293 if (!ARM::DPRRegClass.contains(*SR))
294 continue;
295 bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg;
296 O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]");
297 return false;
298 }
299 }
300 return true;
301 case 'B': // Bitwise inverse of integer or symbol without a preceding #.
302 if (!MI->getOperand(OpNum).isImm())
303 return true;
304 O << ~(MI->getOperand(OpNum).getImm());
305 return false;
306 case 'L': // The low 16 bits of an immediate constant.
307 if (!MI->getOperand(OpNum).isImm())
308 return true;
309 O << (MI->getOperand(OpNum).getImm() & 0xffff);
310 return false;
311 case 'M': { // A register range suitable for LDM/STM.
312 if (!MI->getOperand(OpNum).isReg())
313 return true;
314 const MachineOperand &MO = MI->getOperand(OpNum);
315 unsigned RegBegin = MO.getReg();
316 // This takes advantage of the 2 operand-ness of ldm/stm and that we've
317 // already got the operands in registers that are operands to the
318 // inline asm statement.
319 O << "{";
320 if (ARM::GPRPairRegClass.contains(RegBegin)) {
321 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
322 unsigned Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0);
323 O << ARMInstPrinter::getRegisterName(Reg0) << ", ";
324 RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1);
325 }
326 O << ARMInstPrinter::getRegisterName(RegBegin);
327
328 // FIXME: The register allocator not only may not have given us the
329 // registers in sequence, but may not be in ascending registers. This
330 // will require changes in the register allocator that'll need to be
331 // propagated down here if the operands change.
332 unsigned RegOps = OpNum + 1;
333 while (MI->getOperand(RegOps).isReg()) {
334 O << ", "
335 << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg());
336 RegOps++;
337 }
338
339 O << "}";
340
341 return false;
342 }
343 case 'R': // The most significant register of a pair.
344 case 'Q': { // The least significant register of a pair.
345 if (OpNum == 0)
7
Assuming 'OpNum' is not equal to 0
8
Taking false branch
346 return true;
347 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
348 if (!FlagsOP.isImm())
9
Taking false branch
349 return true;
350 unsigned Flags = FlagsOP.getImm();
351
352 // This operand may not be the one that actually provides the register. If
353 // it's tied to a previous one then we should refer instead to that one
354 // for registers and their classes.
355 unsigned TiedIdx;
356 if (InlineAsm::isUseOperandTiedToDef(Flags, TiedIdx)) {
10
Taking false branch
357 for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) {
358 unsigned OpFlags = MI->getOperand(OpNum).getImm();
359 OpNum += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
360 }
361 Flags = MI->getOperand(OpNum).getImm();
362
363 // Later code expects OpNum to be pointing at the register rather than
364 // the flags.
365 OpNum += 1;
366 }
367
368 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
369 unsigned RC;
11
'RC' declared without an initial value
370 InlineAsm::hasRegClassConstraint(Flags, RC);
12
Calling 'InlineAsm::hasRegClassConstraint'
17
Returning from 'InlineAsm::hasRegClassConstraint'
371 if (RC == ARM::GPRPairRegClassID) {
18
The left operand of '==' is a garbage value
372 if (NumVals != 1)
373 return true;
374 const MachineOperand &MO = MI->getOperand(OpNum);
375 if (!MO.isReg())
376 return true;
377 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
378 unsigned Reg = TRI->getSubReg(MO.getReg(), ExtraCode[0] == 'Q' ?
379 ARM::gsub_0 : ARM::gsub_1);
380 O << ARMInstPrinter::getRegisterName(Reg);
381 return false;
382 }
383 if (NumVals != 2)
384 return true;
385 unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1;
386 if (RegOp >= MI->getNumOperands())
387 return true;
388 const MachineOperand &MO = MI->getOperand(RegOp);
389 if (!MO.isReg())
390 return true;
391 unsigned Reg = MO.getReg();
392 O << ARMInstPrinter::getRegisterName(Reg);
393 return false;
394 }
395
396 case 'e': // The low doubleword register of a NEON quad register.
397 case 'f': { // The high doubleword register of a NEON quad register.
398 if (!MI->getOperand(OpNum).isReg())
399 return true;
400 unsigned Reg = MI->getOperand(OpNum).getReg();
401 if (!ARM::QPRRegClass.contains(Reg))
402 return true;
403 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
404 unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ?
405 ARM::dsub_0 : ARM::dsub_1);
406 O << ARMInstPrinter::getRegisterName(SubReg);
407 return false;
408 }
409
410 // This modifier is not yet supported.
411 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
412 return true;
413 case 'H': { // The highest-numbered register of a pair.
414 const MachineOperand &MO = MI->getOperand(OpNum);
415 if (!MO.isReg())
416 return true;
417 const MachineFunction &MF = *MI->getParent()->getParent();
418 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
419 unsigned Reg = MO.getReg();
420 if(!ARM::GPRPairRegClass.contains(Reg))
421 return false;
422 Reg = TRI->getSubReg(Reg, ARM::gsub_1);
423 O << ARMInstPrinter::getRegisterName(Reg);
424 return false;
425 }
426 }
427 }
428
429 printOperand(MI, OpNum, O);
430 return false;
431}
432
433bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
434 unsigned OpNum, unsigned AsmVariant,
435 const char *ExtraCode,
436 raw_ostream &O) {
437 // Does this asm operand have a single letter operand modifier?
438 if (ExtraCode && ExtraCode[0]) {
439 if (ExtraCode[1] != 0) return true; // Unknown modifier.
440
441 switch (ExtraCode[0]) {
442 case 'A': // A memory operand for a VLD1/VST1 instruction.
443 default: return true; // Unknown modifier.
444 case 'm': // The base register of a memory operand.
445 if (!MI->getOperand(OpNum).isReg())
446 return true;
447 O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg());
448 return false;
449 }
450 }
451
452 const MachineOperand &MO = MI->getOperand(OpNum);
453 assert(MO.isReg() && "unexpected inline asm memory operand")(static_cast <bool> (MO.isReg() && "unexpected inline asm memory operand"
) ? void (0) : __assert_fail ("MO.isReg() && \"unexpected inline asm memory operand\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 453, __extension__ __PRETTY_FUNCTION__))
;
454 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
455 return false;
456}
457
458static bool isThumb(const MCSubtargetInfo& STI) {
459 return STI.getFeatureBits()[ARM::ModeThumb];
460}
461
462void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
463 const MCSubtargetInfo *EndInfo) const {
464 // If either end mode is unknown (EndInfo == NULL) or different than
465 // the start mode, then restore the start mode.
466 const bool WasThumb = isThumb(StartInfo);
467 if (!EndInfo || WasThumb != isThumb(*EndInfo)) {
468 OutStreamer->EmitAssemblerFlag(WasThumb ? MCAF_Code16 : MCAF_Code32);
469 }
470}
471
472void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
473 const Triple &TT = TM.getTargetTriple();
474 // Use unified assembler syntax.
475 OutStreamer->EmitAssemblerFlag(MCAF_SyntaxUnified);
476
477 // Emit ARM Build Attributes
478 if (TT.isOSBinFormatELF())
479 emitAttributes();
480
481 // Use the triple's architecture and subarchitecture to determine
482 // if we're thumb for the purposes of the top level code16 assembler
483 // flag.
484 if (!M.getModuleInlineAsm().empty() && TT.isThumb())
485 OutStreamer->EmitAssemblerFlag(MCAF_Code16);
486}
487
488static void
489emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
490 MachineModuleInfoImpl::StubValueTy &MCSym) {
491 // L_foo$stub:
492 OutStreamer.EmitLabel(StubLabel);
493 // .indirect_symbol _foo
494 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
495
496 if (MCSym.getInt())
497 // External to current translation unit.
498 OutStreamer.EmitIntValue(0, 4/*size*/);
499 else
500 // Internal to current translation unit.
501 //
502 // When we place the LSDA into the TEXT section, the type info
503 // pointers need to be indirect and pc-rel. We accomplish this by
504 // using NLPs; however, sometimes the types are local to the file.
505 // We need to fill in the value for the NLP in those cases.
506 OutStreamer.EmitValue(
507 MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
508 4 /*size*/);
509}
510
511
512void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
513 const Triple &TT = TM.getTargetTriple();
514 if (TT.isOSBinFormatMachO()) {
515 // All darwin targets use mach-o.
516 const TargetLoweringObjectFileMachO &TLOFMacho =
517 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
518 MachineModuleInfoMachO &MMIMacho =
519 MMI->getObjFileInfo<MachineModuleInfoMachO>();
520
521 // Output non-lazy-pointers for external and common global variables.
522 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
523
524 if (!Stubs.empty()) {
525 // Switch with ".non_lazy_symbol_pointer" directive.
526 OutStreamer->SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
527 EmitAlignment(2);
528
529 for (auto &Stub : Stubs)
530 emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
531
532 Stubs.clear();
533 OutStreamer->AddBlankLine();
534 }
535
536 Stubs = MMIMacho.GetThreadLocalGVStubList();
537 if (!Stubs.empty()) {
538 // Switch with ".non_lazy_symbol_pointer" directive.
539 OutStreamer->SwitchSection(TLOFMacho.getThreadLocalPointerSection());
540 EmitAlignment(2);
541
542 for (auto &Stub : Stubs)
543 emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
544
545 Stubs.clear();
546 OutStreamer->AddBlankLine();
547 }
548
549 // Funny Darwin hack: This flag tells the linker that no global symbols
550 // contain code that falls through to other global symbols (e.g. the obvious
551 // implementation of multiple entry points). If this doesn't occur, the
552 // linker can safely perform dead code stripping. Since LLVM never
553 // generates code that does this, it is always safe to set.
554 OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
555 }
556
557 // The last attribute to be emitted is ABI_optimization_goals
558 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
559 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
560
561 if (OptimizationGoals > 0 &&
562 (Subtarget->isTargetAEABI() || Subtarget->isTargetGNUAEABI() ||
563 Subtarget->isTargetMuslAEABI()))
564 ATS.emitAttribute(ARMBuildAttrs::ABI_optimization_goals, OptimizationGoals);
565 OptimizationGoals = -1;
566
567 ATS.finishAttributeSection();
568}
569
570//===----------------------------------------------------------------------===//
571// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
572// FIXME:
573// The following seem like one-off assembler flags, but they actually need
574// to appear in the .ARM.attributes section in ELF.
575// Instead of subclassing the MCELFStreamer, we do the work here.
576
577// Returns true if all functions have the same function attribute value.
578// It also returns true when the module has no functions.
579static bool checkFunctionsAttributeConsistency(const Module &M, StringRef Attr,
580 StringRef Value) {
581 return !any_of(M, [&](const Function &F) {
582 return F.getFnAttribute(Attr).getValueAsString() != Value;
583 });
584}
585
586void ARMAsmPrinter::emitAttributes() {
587 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
588 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
589
590 ATS.emitTextAttribute(ARMBuildAttrs::conformance, "2.09");
591
592 ATS.switchVendor("aeabi");
593
594 // Compute ARM ELF Attributes based on the default subtarget that
595 // we'd have constructed. The existing ARM behavior isn't LTO clean
596 // anyhow.
597 // FIXME: For ifunc related functions we could iterate over and look
598 // for a feature string that doesn't match the default one.
599 const Triple &TT = TM.getTargetTriple();
600 StringRef CPU = TM.getTargetCPU();
601 StringRef FS = TM.getTargetFeatureString();
602 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
603 if (!FS.empty()) {
604 if (!ArchFS.empty())
605 ArchFS = (Twine(ArchFS) + "," + FS).str();
606 else
607 ArchFS = FS;
608 }
609 const ARMBaseTargetMachine &ATM =
610 static_cast<const ARMBaseTargetMachine &>(TM);
611 const ARMSubtarget STI(TT, CPU, ArchFS, ATM, ATM.isLittleEndian());
612
613 // Emit build attributes for the available hardware.
614 ATS.emitTargetAttributes(STI);
615
616 // RW data addressing.
617 if (isPositionIndependent()) {
618 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RW_data,
619 ARMBuildAttrs::AddressRWPCRel);
620 } else if (STI.isRWPI()) {
621 // RWPI specific attributes.
622 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RW_data,
623 ARMBuildAttrs::AddressRWSBRel);
624 }
625
626 // RO data addressing.
627 if (isPositionIndependent() || STI.isROPI()) {
628 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RO_data,
629 ARMBuildAttrs::AddressROPCRel);
630 }
631
632 // GOT use.
633 if (isPositionIndependent()) {
634 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use,
635 ARMBuildAttrs::AddressGOT);
636 } else {
637 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use,
638 ARMBuildAttrs::AddressDirect);
639 }
640
641 // Set FP Denormals.
642 if (checkFunctionsAttributeConsistency(*MMI->getModule(),
643 "denormal-fp-math",
644 "preserve-sign") ||
645 TM.Options.FPDenormalMode == FPDenormal::PreserveSign)
646 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
647 ARMBuildAttrs::PreserveFPSign);
648 else if (checkFunctionsAttributeConsistency(*MMI->getModule(),
649 "denormal-fp-math",
650 "positive-zero") ||
651 TM.Options.FPDenormalMode == FPDenormal::PositiveZero)
652 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
653 ARMBuildAttrs::PositiveZero);
654 else if (!TM.Options.UnsafeFPMath)
655 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
656 ARMBuildAttrs::IEEEDenormals);
657 else {
658 if (!STI.hasVFP2()) {
659 // When the target doesn't have an FPU (by design or
660 // intention), the assumptions made on the software support
661 // mirror that of the equivalent hardware support *if it
662 // existed*. For v7 and better we indicate that denormals are
663 // flushed preserving sign, and for V6 we indicate that
664 // denormals are flushed to positive zero.
665 if (STI.hasV7Ops())
666 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
667 ARMBuildAttrs::PreserveFPSign);
668 } else if (STI.hasVFP3()) {
669 // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is,
670 // the sign bit of the zero matches the sign bit of the input or
671 // result that is being flushed to zero.
672 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
673 ARMBuildAttrs::PreserveFPSign);
674 }
675 // For VFPv2 implementations it is implementation defined as
676 // to whether denormals are flushed to positive zero or to
677 // whatever the sign of zero is (ARM v7AR ARM 2.7.5). Historically
678 // LLVM has chosen to flush this to positive zero (most likely for
679 // GCC compatibility), so that's the chosen value here (the
680 // absence of its emission implies zero).
681 }
682
683 // Set FP exceptions and rounding
684 if (checkFunctionsAttributeConsistency(*MMI->getModule(),
685 "no-trapping-math", "true") ||
686 TM.Options.NoTrappingFPMath)
687 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
688 ARMBuildAttrs::Not_Allowed);
689 else if (!TM.Options.UnsafeFPMath) {
690 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, ARMBuildAttrs::Allowed);
691
692 // If the user has permitted this code to choose the IEEE 754
693 // rounding at run-time, emit the rounding attribute.
694 if (TM.Options.HonorSignDependentRoundingFPMathOption)
695 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_rounding, ARMBuildAttrs::Allowed);
696 }
697
698 // TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath is the
699 // equivalent of GCC's -ffinite-math-only flag.
700 if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)
701 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
702 ARMBuildAttrs::Allowed);
703 else
704 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
705 ARMBuildAttrs::AllowIEEE754);
706
707 // FIXME: add more flags to ARMBuildAttributes.h
708 // 8-bytes alignment stuff.
709 ATS.emitAttribute(ARMBuildAttrs::ABI_align_needed, 1);
710 ATS.emitAttribute(ARMBuildAttrs::ABI_align_preserved, 1);
711
712 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
713 if (STI.isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard)
714 ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, ARMBuildAttrs::HardFPAAPCS);
715
716 // FIXME: To support emitting this build attribute as GCC does, the
717 // -mfp16-format option and associated plumbing must be
718 // supported. For now the __fp16 type is exposed by default, so this
719 // attribute should be emitted with value 1.
720 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_16bit_format,
721 ARMBuildAttrs::FP16FormatIEEE);
722
723 if (MMI) {
724 if (const Module *SourceModule = MMI->getModule()) {
725 // ABI_PCS_wchar_t to indicate wchar_t width
726 // FIXME: There is no way to emit value 0 (wchar_t prohibited).
727 if (auto WCharWidthValue = mdconst::extract_or_null<ConstantInt>(
728 SourceModule->getModuleFlag("wchar_size"))) {
729 int WCharWidth = WCharWidthValue->getZExtValue();
730 assert((WCharWidth == 2 || WCharWidth == 4) &&(static_cast <bool> ((WCharWidth == 2 || WCharWidth == 4
) && "wchar_t width must be 2 or 4 bytes") ? void (0)
: __assert_fail ("(WCharWidth == 2 || WCharWidth == 4) && \"wchar_t width must be 2 or 4 bytes\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 731, __extension__ __PRETTY_FUNCTION__))
731 "wchar_t width must be 2 or 4 bytes")(static_cast <bool> ((WCharWidth == 2 || WCharWidth == 4
) && "wchar_t width must be 2 or 4 bytes") ? void (0)
: __assert_fail ("(WCharWidth == 2 || WCharWidth == 4) && \"wchar_t width must be 2 or 4 bytes\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 731, __extension__ __PRETTY_FUNCTION__))
;
732 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_wchar_t, WCharWidth);
733 }
734
735 // ABI_enum_size to indicate enum width
736 // FIXME: There is no way to emit value 0 (enums prohibited) or value 3
737 // (all enums contain a value needing 32 bits to encode).
738 if (auto EnumWidthValue = mdconst::extract_or_null<ConstantInt>(
739 SourceModule->getModuleFlag("min_enum_size"))) {
740 int EnumWidth = EnumWidthValue->getZExtValue();
741 assert((EnumWidth == 1 || EnumWidth == 4) &&(static_cast <bool> ((EnumWidth == 1 || EnumWidth == 4)
&& "Minimum enum width must be 1 or 4 bytes") ? void
(0) : __assert_fail ("(EnumWidth == 1 || EnumWidth == 4) && \"Minimum enum width must be 1 or 4 bytes\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 742, __extension__ __PRETTY_FUNCTION__))
742 "Minimum enum width must be 1 or 4 bytes")(static_cast <bool> ((EnumWidth == 1 || EnumWidth == 4)
&& "Minimum enum width must be 1 or 4 bytes") ? void
(0) : __assert_fail ("(EnumWidth == 1 || EnumWidth == 4) && \"Minimum enum width must be 1 or 4 bytes\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 742, __extension__ __PRETTY_FUNCTION__))
;
743 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;
744 ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr);
745 }
746 }
747 }
748
749 // We currently do not support using R9 as the TLS pointer.
750 if (STI.isRWPI())
751 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use,
752 ARMBuildAttrs::R9IsSB);
753 else if (STI.isR9Reserved())
754 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use,
755 ARMBuildAttrs::R9Reserved);
756 else
757 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use,
758 ARMBuildAttrs::R9IsGPR);
759}
760
761//===----------------------------------------------------------------------===//
762
763static MCSymbol *getPICLabel(StringRef Prefix, unsigned FunctionNumber,
764 unsigned LabelId, MCContext &Ctx) {
765
766 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix)
767 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
768 return Label;
769}
770
771static MCSymbolRefExpr::VariantKind
772getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
773 switch (Modifier) {
774 case ARMCP::no_modifier:
775 return MCSymbolRefExpr::VK_None;
776 case ARMCP::TLSGD:
777 return MCSymbolRefExpr::VK_TLSGD;
778 case ARMCP::TPOFF:
779 return MCSymbolRefExpr::VK_TPOFF;
780 case ARMCP::GOTTPOFF:
781 return MCSymbolRefExpr::VK_GOTTPOFF;
782 case ARMCP::SBREL:
783 return MCSymbolRefExpr::VK_ARM_SBREL;
784 case ARMCP::GOT_PREL:
785 return MCSymbolRefExpr::VK_ARM_GOT_PREL;
786 case ARMCP::SECREL:
787 return MCSymbolRefExpr::VK_SECREL;
788 }
789 llvm_unreachable("Invalid ARMCPModifier!")::llvm::llvm_unreachable_internal("Invalid ARMCPModifier!", "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 789)
;
790}
791
792MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV,
793 unsigned char TargetFlags) {
794 if (Subtarget->isTargetMachO()) {
795 bool IsIndirect =
796 (TargetFlags & ARMII::MO_NONLAZY) && Subtarget->isGVIndirectSymbol(GV);
797
798 if (!IsIndirect)
799 return getSymbol(GV);
800
801 // FIXME: Remove this when Darwin transition to @GOT like syntax.
802 MCSymbol *MCSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
803 MachineModuleInfoMachO &MMIMachO =
804 MMI->getObjFileInfo<MachineModuleInfoMachO>();
805 MachineModuleInfoImpl::StubValueTy &StubSym =
806 GV->isThreadLocal() ? MMIMachO.getThreadLocalGVStubEntry(MCSym)
807 : MMIMachO.getGVStubEntry(MCSym);
808
809 if (!StubSym.getPointer())
810 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
811 !GV->hasInternalLinkage());
812 return MCSym;
813 } else if (Subtarget->isTargetCOFF()) {
814 assert(Subtarget->isTargetWindows() &&(static_cast <bool> (Subtarget->isTargetWindows() &&
"Windows is the only supported COFF target") ? void (0) : __assert_fail
("Subtarget->isTargetWindows() && \"Windows is the only supported COFF target\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 815, __extension__ __PRETTY_FUNCTION__))
815 "Windows is the only supported COFF target")(static_cast <bool> (Subtarget->isTargetWindows() &&
"Windows is the only supported COFF target") ? void (0) : __assert_fail
("Subtarget->isTargetWindows() && \"Windows is the only supported COFF target\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 815, __extension__ __PRETTY_FUNCTION__))
;
816
817 bool IsIndirect = (TargetFlags & ARMII::MO_DLLIMPORT);
818 if (!IsIndirect)
819 return getSymbol(GV);
820
821 SmallString<128> Name;
822 Name = "__imp_";
823 getNameWithPrefix(Name, GV);
824
825 return OutContext.getOrCreateSymbol(Name);
826 } else if (Subtarget->isTargetELF()) {
827 return getSymbol(GV);
828 }
829 llvm_unreachable("unexpected target")::llvm::llvm_unreachable_internal("unexpected target", "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 829)
;
830}
831
832void ARMAsmPrinter::
833EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
834 const DataLayout &DL = getDataLayout();
835 int Size = DL.getTypeAllocSize(MCPV->getType());
836
837 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
838
839 if (ACPV->isPromotedGlobal()) {
840 // This constant pool entry is actually a global whose storage has been
841 // promoted into the constant pool. This global may be referenced still
842 // by debug information, and due to the way AsmPrinter is set up, the debug
843 // info is immutable by the time we decide to promote globals to constant
844 // pools. Because of this, we need to ensure we emit a symbol for the global
845 // with private linkage (the default) so debug info can refer to it.
846 //
847 // However, if this global is promoted into several functions we must ensure
848 // we don't try and emit duplicate symbols!
849 auto *ACPC = cast<ARMConstantPoolConstant>(ACPV);
850 for (const auto *GV : ACPC->promotedGlobals()) {
851 if (!EmittedPromotedGlobalLabels.count(GV)) {
852 MCSymbol *GVSym = getSymbol(GV);
853 OutStreamer->EmitLabel(GVSym);
854 EmittedPromotedGlobalLabels.insert(GV);
855 }
856 }
857 return EmitGlobalConstant(DL, ACPC->getPromotedGlobalInit());
858 }
859
860 MCSymbol *MCSym;
861 if (ACPV->isLSDA()) {
862 MCSym = getCurExceptionSym();
863 } else if (ACPV->isBlockAddress()) {
864 const BlockAddress *BA =
865 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
866 MCSym = GetBlockAddressSymbol(BA);
867 } else if (ACPV->isGlobalValue()) {
868 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
869
870 // On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so
871 // flag the global as MO_NONLAZY.
872 unsigned char TF = Subtarget->isTargetMachO() ? ARMII::MO_NONLAZY : 0;
873 MCSym = GetARMGVSymbol(GV, TF);
874 } else if (ACPV->isMachineBasicBlock()) {
875 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
876 MCSym = MBB->getSymbol();
877 } else {
878 assert(ACPV->isExtSymbol() && "unrecognized constant pool value")(static_cast <bool> (ACPV->isExtSymbol() && "unrecognized constant pool value"
) ? void (0) : __assert_fail ("ACPV->isExtSymbol() && \"unrecognized constant pool value\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 878, __extension__ __PRETTY_FUNCTION__))
;
879 auto Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
880 MCSym = GetExternalSymbolSymbol(Sym);
881 }
882
883 // Create an MCSymbol for the reference.
884 const MCExpr *Expr =
885 MCSymbolRefExpr::create(MCSym, getModifierVariantKind(ACPV->getModifier()),
886 OutContext);
887
888 if (ACPV->getPCAdjustment()) {
889 MCSymbol *PCLabel =
890 getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
891 ACPV->getLabelId(), OutContext);
892 const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext);
893 PCRelExpr =
894 MCBinaryExpr::createAdd(PCRelExpr,
895 MCConstantExpr::create(ACPV->getPCAdjustment(),
896 OutContext),
897 OutContext);
898 if (ACPV->mustAddCurrentAddress()) {
899 // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
900 // label, so just emit a local label end reference that instead.
901 MCSymbol *DotSym = OutContext.createTempSymbol();
902 OutStreamer->EmitLabel(DotSym);
903 const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
904 PCRelExpr = MCBinaryExpr::createSub(PCRelExpr, DotExpr, OutContext);
905 }
906 Expr = MCBinaryExpr::createSub(Expr, PCRelExpr, OutContext);
907 }
908 OutStreamer->EmitValue(Expr, Size);
909}
910
911void ARMAsmPrinter::EmitJumpTableAddrs(const MachineInstr *MI) {
912 const MachineOperand &MO1 = MI->getOperand(1);
913 unsigned JTI = MO1.getIndex();
914
915 // Make sure the Thumb jump table is 4-byte aligned. This will be a nop for
916 // ARM mode tables.
917 EmitAlignment(2);
918
919 // Emit a label for the jump table.
920 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
921 OutStreamer->EmitLabel(JTISymbol);
922
923 // Mark the jump table as data-in-code.
924 OutStreamer->EmitDataRegion(MCDR_DataRegionJT32);
925
926 // Emit each entry of the table.
927 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
928 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
929 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
930
931 for (MachineBasicBlock *MBB : JTBBs) {
932 // Construct an MCExpr for the entry. We want a value of the form:
933 // (BasicBlockAddr - TableBeginAddr)
934 //
935 // For example, a table with entries jumping to basic blocks BB0 and BB1
936 // would look like:
937 // LJTI_0_0:
938 // .word (LBB0 - LJTI_0_0)
939 // .word (LBB1 - LJTI_0_0)
940 const MCExpr *Expr = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
941
942 if (isPositionIndependent() || Subtarget->isROPI())
943 Expr = MCBinaryExpr::createSub(Expr, MCSymbolRefExpr::create(JTISymbol,
944 OutContext),
945 OutContext);
946 // If we're generating a table of Thumb addresses in static relocation
947 // model, we need to add one to keep interworking correctly.
948 else if (AFI->isThumbFunction())
949 Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(1,OutContext),
950 OutContext);
951 OutStreamer->EmitValue(Expr, 4);
952 }
953 // Mark the end of jump table data-in-code region.
954 OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
955}
956
957void ARMAsmPrinter::EmitJumpTableInsts(const MachineInstr *MI) {
958 const MachineOperand &MO1 = MI->getOperand(1);
959 unsigned JTI = MO1.getIndex();
960
961 // Make sure the Thumb jump table is 4-byte aligned. This will be a nop for
962 // ARM mode tables.
963 EmitAlignment(2);
964
965 // Emit a label for the jump table.
966 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
967 OutStreamer->EmitLabel(JTISymbol);
968
969 // Emit each entry of the table.
970 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
971 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
972 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
973
974 for (MachineBasicBlock *MBB : JTBBs) {
975 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::create(MBB->getSymbol(),
976 OutContext);
977 // If this isn't a TBB or TBH, the entries are direct branch instructions.
978 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2B)
979 .addExpr(MBBSymbolExpr)
980 .addImm(ARMCC::AL)
981 .addReg(0));
982 }
983}
984
985void ARMAsmPrinter::EmitJumpTableTBInst(const MachineInstr *MI,
986 unsigned OffsetWidth) {
987 assert((OffsetWidth == 1 || OffsetWidth == 2) && "invalid tbb/tbh width")(static_cast <bool> ((OffsetWidth == 1 || OffsetWidth ==
2) && "invalid tbb/tbh width") ? void (0) : __assert_fail
("(OffsetWidth == 1 || OffsetWidth == 2) && \"invalid tbb/tbh width\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 987, __extension__ __PRETTY_FUNCTION__))
;
988 const MachineOperand &MO1 = MI->getOperand(1);
989 unsigned JTI = MO1.getIndex();
990
991 if (Subtarget->isThumb1Only())
992 EmitAlignment(2);
993
994 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
995 OutStreamer->EmitLabel(JTISymbol);
996
997 // Emit each entry of the table.
998 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
999 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1000 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1001
1002 // Mark the jump table as data-in-code.
1003 OutStreamer->EmitDataRegion(OffsetWidth == 1 ? MCDR_DataRegionJT8
1004 : MCDR_DataRegionJT16);
1005
1006 for (auto MBB : JTBBs) {
1007 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::create(MBB->getSymbol(),
1008 OutContext);
1009 // Otherwise it's an offset from the dispatch instruction. Construct an
1010 // MCExpr for the entry. We want a value of the form:
1011 // (BasicBlockAddr - TBBInstAddr + 4) / 2
1012 //
1013 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1014 // would look like:
1015 // LJTI_0_0:
1016 // .byte (LBB0 - (LCPI0_0 + 4)) / 2
1017 // .byte (LBB1 - (LCPI0_0 + 4)) / 2
1018 // where LCPI0_0 is a label defined just before the TBB instruction using
1019 // this table.
1020 MCSymbol *TBInstPC = GetCPISymbol(MI->getOperand(0).getImm());
1021 const MCExpr *Expr = MCBinaryExpr::createAdd(
1022 MCSymbolRefExpr::create(TBInstPC, OutContext),
1023 MCConstantExpr::create(4, OutContext), OutContext);
1024 Expr = MCBinaryExpr::createSub(MBBSymbolExpr, Expr, OutContext);
1025 Expr = MCBinaryExpr::createDiv(Expr, MCConstantExpr::create(2, OutContext),
1026 OutContext);
1027 OutStreamer->EmitValue(Expr, OffsetWidth);
1028 }
1029 // Mark the end of jump table data-in-code region. 32-bit offsets use
1030 // actual branch instructions here, so we don't mark those as a data-region
1031 // at all.
1032 OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
1033
1034 // Make sure the next instruction is 2-byte aligned.
1035 EmitAlignment(1);
1036}
1037
1038void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
1039 assert(MI->getFlag(MachineInstr::FrameSetup) &&(static_cast <bool> (MI->getFlag(MachineInstr::FrameSetup
) && "Only instruction which are involved into frame setup code are allowed"
) ? void (0) : __assert_fail ("MI->getFlag(MachineInstr::FrameSetup) && \"Only instruction which are involved into frame setup code are allowed\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1040, __extension__ __PRETTY_FUNCTION__))
1040 "Only instruction which are involved into frame setup code are allowed")(static_cast <bool> (MI->getFlag(MachineInstr::FrameSetup
) && "Only instruction which are involved into frame setup code are allowed"
) ? void (0) : __assert_fail ("MI->getFlag(MachineInstr::FrameSetup) && \"Only instruction which are involved into frame setup code are allowed\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1040, __extension__ __PRETTY_FUNCTION__))
;
1041
1042 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1043 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1044 const MachineFunction &MF = *MI->getParent()->getParent();
1045 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
1046 const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>();
1047
1048 unsigned FramePtr = RegInfo->getFrameRegister(MF);
1049 unsigned Opc = MI->getOpcode();
1050 unsigned SrcReg, DstReg;
1051
1052 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
1053 // Two special cases:
1054 // 1) tPUSH does not have src/dst regs.
1055 // 2) for Thumb1 code we sometimes materialize the constant via constpool
1056 // load. Yes, this is pretty fragile, but for now I don't see better
1057 // way... :(
1058 SrcReg = DstReg = ARM::SP;
1059 } else {
1060 SrcReg = MI->getOperand(1).getReg();
1061 DstReg = MI->getOperand(0).getReg();
1062 }
1063
1064 // Try to figure out the unwinding opcode out of src / dst regs.
1065 if (MI->mayStore()) {
1066 // Register saves.
1067 assert(DstReg == ARM::SP &&(static_cast <bool> (DstReg == ARM::SP && "Only stack pointer as a destination reg is supported"
) ? void (0) : __assert_fail ("DstReg == ARM::SP && \"Only stack pointer as a destination reg is supported\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1068, __extension__ __PRETTY_FUNCTION__))
1068 "Only stack pointer as a destination reg is supported")(static_cast <bool> (DstReg == ARM::SP && "Only stack pointer as a destination reg is supported"
) ? void (0) : __assert_fail ("DstReg == ARM::SP && \"Only stack pointer as a destination reg is supported\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1068, __extension__ __PRETTY_FUNCTION__))
;
1069
1070 SmallVector<unsigned, 4> RegList;
1071 // Skip src & dst reg, and pred ops.
1072 unsigned StartOp = 2 + 2;
1073 // Use all the operands.
1074 unsigned NumOffset = 0;
1075 // Amount of SP adjustment folded into a push.
1076 unsigned Pad = 0;
1077
1078 switch (Opc) {
1079 default:
1080 MI->print(errs());
1081 llvm_unreachable("Unsupported opcode for unwinding information")::llvm::llvm_unreachable_internal("Unsupported opcode for unwinding information"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1081)
;
1082 case ARM::tPUSH:
1083 // Special case here: no src & dst reg, but two extra imp ops.
1084 StartOp = 2; NumOffset = 2;
1085 LLVM_FALLTHROUGH[[clang::fallthrough]];
1086 case ARM::STMDB_UPD:
1087 case ARM::t2STMDB_UPD:
1088 case ARM::VSTMDDB_UPD:
1089 assert(SrcReg == ARM::SP &&(static_cast <bool> (SrcReg == ARM::SP && "Only stack pointer as a source reg is supported"
) ? void (0) : __assert_fail ("SrcReg == ARM::SP && \"Only stack pointer as a source reg is supported\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1090, __extension__ __PRETTY_FUNCTION__))
1090 "Only stack pointer as a source reg is supported")(static_cast <bool> (SrcReg == ARM::SP && "Only stack pointer as a source reg is supported"
) ? void (0) : __assert_fail ("SrcReg == ARM::SP && \"Only stack pointer as a source reg is supported\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1090, __extension__ __PRETTY_FUNCTION__))
;
1091 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
1092 i != NumOps; ++i) {
1093 const MachineOperand &MO = MI->getOperand(i);
1094 // Actually, there should never be any impdef stuff here. Skip it
1095 // temporary to workaround PR11902.
1096 if (MO.isImplicit())
1097 continue;
1098 // Registers, pushed as a part of folding an SP update into the
1099 // push instruction are marked as undef and should not be
1100 // restored when unwinding, because the function can modify the
1101 // corresponding stack slots.
1102 if (MO.isUndef()) {
1103 assert(RegList.empty() &&(static_cast <bool> (RegList.empty() && "Pad registers must come before restored ones"
) ? void (0) : __assert_fail ("RegList.empty() && \"Pad registers must come before restored ones\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1104, __extension__ __PRETTY_FUNCTION__))
1104 "Pad registers must come before restored ones")(static_cast <bool> (RegList.empty() && "Pad registers must come before restored ones"
) ? void (0) : __assert_fail ("RegList.empty() && \"Pad registers must come before restored ones\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1104, __extension__ __PRETTY_FUNCTION__))
;
1105 Pad += 4;
1106 continue;
1107 }
1108 RegList.push_back(MO.getReg());
1109 }
1110 break;
1111 case ARM::STR_PRE_IMM:
1112 case ARM::STR_PRE_REG:
1113 case ARM::t2STR_PRE:
1114 assert(MI->getOperand(2).getReg() == ARM::SP &&(static_cast <bool> (MI->getOperand(2).getReg() == ARM
::SP && "Only stack pointer as a source reg is supported"
) ? void (0) : __assert_fail ("MI->getOperand(2).getReg() == ARM::SP && \"Only stack pointer as a source reg is supported\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1115, __extension__ __PRETTY_FUNCTION__))
1115 "Only stack pointer as a source reg is supported")(static_cast <bool> (MI->getOperand(2).getReg() == ARM
::SP && "Only stack pointer as a source reg is supported"
) ? void (0) : __assert_fail ("MI->getOperand(2).getReg() == ARM::SP && \"Only stack pointer as a source reg is supported\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1115, __extension__ __PRETTY_FUNCTION__))
;
1116 RegList.push_back(SrcReg);
1117 break;
1118 }
1119 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) {
1120 ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
1121 // Account for the SP adjustment, folded into the push.
1122 if (Pad)
1123 ATS.emitPad(Pad);
1124 }
1125 } else {
1126 // Changes of stack / frame pointer.
1127 if (SrcReg == ARM::SP) {
1128 int64_t Offset = 0;
1129 switch (Opc) {
1130 default:
1131 MI->print(errs());
1132 llvm_unreachable("Unsupported opcode for unwinding information")::llvm::llvm_unreachable_internal("Unsupported opcode for unwinding information"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1132)
;
1133 case ARM::MOVr:
1134 case ARM::tMOVr:
1135 Offset = 0;
1136 break;
1137 case ARM::ADDri:
1138 case ARM::t2ADDri:
1139 Offset = -MI->getOperand(2).getImm();
1140 break;
1141 case ARM::SUBri:
1142 case ARM::t2SUBri:
1143 Offset = MI->getOperand(2).getImm();
1144 break;
1145 case ARM::tSUBspi:
1146 Offset = MI->getOperand(2).getImm()*4;
1147 break;
1148 case ARM::tADDspi:
1149 case ARM::tADDrSPi:
1150 Offset = -MI->getOperand(2).getImm()*4;
1151 break;
1152 case ARM::tLDRpci: {
1153 // Grab the constpool index and check, whether it corresponds to
1154 // original or cloned constpool entry.
1155 unsigned CPI = MI->getOperand(1).getIndex();
1156 const MachineConstantPool *MCP = MF.getConstantPool();
1157 if (CPI >= MCP->getConstants().size())
1158 CPI = AFI.getOriginalCPIdx(CPI);
1159 assert(CPI != -1U && "Invalid constpool index")(static_cast <bool> (CPI != -1U && "Invalid constpool index"
) ? void (0) : __assert_fail ("CPI != -1U && \"Invalid constpool index\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1159, __extension__ __PRETTY_FUNCTION__))
;
1160
1161 // Derive the actual offset.
1162 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1163 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry")(static_cast <bool> (!CPE.isMachineConstantPoolEntry() &&
"Invalid constpool entry") ? void (0) : __assert_fail ("!CPE.isMachineConstantPoolEntry() && \"Invalid constpool entry\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1163, __extension__ __PRETTY_FUNCTION__))
;
1164 // FIXME: Check for user, it should be "add" instruction!
1165 Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
1166 break;
1167 }
1168 }
1169
1170 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) {
1171 if (DstReg == FramePtr && FramePtr != ARM::SP)
1172 // Set-up of the frame pointer. Positive values correspond to "add"
1173 // instruction.
1174 ATS.emitSetFP(FramePtr, ARM::SP, -Offset);
1175 else if (DstReg == ARM::SP) {
1176 // Change of SP by an offset. Positive values correspond to "sub"
1177 // instruction.
1178 ATS.emitPad(Offset);
1179 } else {
1180 // Move of SP to a register. Positive values correspond to an "add"
1181 // instruction.
1182 ATS.emitMovSP(DstReg, -Offset);
1183 }
1184 }
1185 } else if (DstReg == ARM::SP) {
1186 MI->print(errs());
1187 llvm_unreachable("Unsupported opcode for unwinding information")::llvm::llvm_unreachable_internal("Unsupported opcode for unwinding information"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1187)
;
1188 }
1189 else {
1190 MI->print(errs());
1191 llvm_unreachable("Unsupported opcode for unwinding information")::llvm::llvm_unreachable_internal("Unsupported opcode for unwinding information"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1191)
;
1192 }
1193 }
1194}
1195
1196// Simple pseudo-instructions have their lowering (with expansion to real
1197// instructions) auto-generated.
1198#include "ARMGenMCPseudoLowering.inc"
1199
1200void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1201 const DataLayout &DL = getDataLayout();
1202 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1203 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1204
1205 const MachineFunction &MF = *MI->getParent()->getParent();
1206 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
1207 unsigned FramePtr = STI.useR7AsFramePointer() ? ARM::R7 : ARM::R11;
1208
1209 // If we just ended a constant pool, mark it as such.
1210 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
1211 OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
1212 InConstantPool = false;
1213 }
1214
1215 // Emit unwinding stuff for frame-related instructions
1216 if (Subtarget->isTargetEHABICompatible() &&
1217 MI->getFlag(MachineInstr::FrameSetup))
1218 EmitUnwindingInstruction(MI);
1219
1220 // Do any auto-generated pseudo lowerings.
1221 if (emitPseudoExpansionLowering(*OutStreamer, MI))
1222 return;
1223
1224 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&(static_cast <bool> (!convertAddSubFlagsOpcode(MI->getOpcode
()) && "Pseudo flag setting opcode should be expanded early"
) ? void (0) : __assert_fail ("!convertAddSubFlagsOpcode(MI->getOpcode()) && \"Pseudo flag setting opcode should be expanded early\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1225, __extension__ __PRETTY_FUNCTION__))
1225 "Pseudo flag setting opcode should be expanded early")(static_cast <bool> (!convertAddSubFlagsOpcode(MI->getOpcode
()) && "Pseudo flag setting opcode should be expanded early"
) ? void (0) : __assert_fail ("!convertAddSubFlagsOpcode(MI->getOpcode()) && \"Pseudo flag setting opcode should be expanded early\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1225, __extension__ __PRETTY_FUNCTION__))
;
1226
1227 // Check for manual lowerings.
1228 unsigned Opc = MI->getOpcode();
1229 switch (Opc) {
1230 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass")::llvm::llvm_unreachable_internal("Should be lowered by thumb2it pass"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1230)
;
1231 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing")::llvm::llvm_unreachable_internal("Should be handled by generic printing"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1231)
;
1232 case ARM::LEApcrel:
1233 case ARM::tLEApcrel:
1234 case ARM::t2LEApcrel: {
1235 // FIXME: Need to also handle globals and externals
1236 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex());
1237 EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
1238 ARM::t2LEApcrel ? ARM::t2ADR
1239 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1240 : ARM::ADR))
1241 .addReg(MI->getOperand(0).getReg())
1242 .addExpr(MCSymbolRefExpr::create(CPISymbol, OutContext))
1243 // Add predicate operands.
1244 .addImm(MI->getOperand(2).getImm())
1245 .addReg(MI->getOperand(3).getReg()));
1246 return;
1247 }
1248 case ARM::LEApcrelJT:
1249 case ARM::tLEApcrelJT:
1250 case ARM::t2LEApcrelJT: {
1251 MCSymbol *JTIPICSymbol =
1252 GetARMJTIPICJumpTableLabel(MI->getOperand(1).getIndex());
1253 EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
1254 ARM::t2LEApcrelJT ? ARM::t2ADR
1255 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1256 : ARM::ADR))
1257 .addReg(MI->getOperand(0).getReg())
1258 .addExpr(MCSymbolRefExpr::create(JTIPICSymbol, OutContext))
1259 // Add predicate operands.
1260 .addImm(MI->getOperand(2).getImm())
1261 .addReg(MI->getOperand(3).getReg()));
1262 return;
1263 }
1264 // Darwin call instructions are just normal call instructions with different
1265 // clobber semantics (they clobber R9).
1266 case ARM::BX_CALL: {
1267 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
1268 .addReg(ARM::LR)
1269 .addReg(ARM::PC)
1270 // Add predicate operands.
1271 .addImm(ARMCC::AL)
1272 .addReg(0)
1273 // Add 's' bit operand (always reg0 for this)
1274 .addReg(0));
1275
1276 assert(Subtarget->hasV4TOps())(static_cast <bool> (Subtarget->hasV4TOps()) ? void (
0) : __assert_fail ("Subtarget->hasV4TOps()", "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1276, __extension__ __PRETTY_FUNCTION__))
;
1277 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
1278 .addReg(MI->getOperand(0).getReg()));
1279 return;
1280 }
1281 case ARM::tBX_CALL: {
1282 if (Subtarget->hasV5TOps())
1283 llvm_unreachable("Expected BLX to be selected for v5t+")::llvm::llvm_unreachable_internal("Expected BLX to be selected for v5t+"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1283)
;
1284
1285 // On ARM v4t, when doing a call from thumb mode, we need to ensure
1286 // that the saved lr has its LSB set correctly (the arch doesn't
1287 // have blx).
1288 // So here we generate a bl to a small jump pad that does bx rN.
1289 // The jump pads are emitted after the function body.
1290
1291 unsigned TReg = MI->getOperand(0).getReg();
1292 MCSymbol *TRegSym = nullptr;
1293 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
1294 if (TIP.first == TReg) {
1295 TRegSym = TIP.second;
1296 break;
1297 }
1298 }
1299
1300 if (!TRegSym) {
1301 TRegSym = OutContext.createTempSymbol();
1302 ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym));
1303 }
1304
1305 // Create a link-saving branch to the Reg Indirect Jump Pad.
1306 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tBL)
1307 // Predicate comes first here.
1308 .addImm(ARMCC::AL).addReg(0)
1309 .addExpr(MCSymbolRefExpr::create(TRegSym, OutContext)));
1310 return;
1311 }
1312 case ARM::BMOVPCRX_CALL: {
1313 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
1314 .addReg(ARM::LR)
1315 .addReg(ARM::PC)
1316 // Add predicate operands.
1317 .addImm(ARMCC::AL)
1318 .addReg(0)
1319 // Add 's' bit operand (always reg0 for this)
1320 .addReg(0));
1321
1322 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
1323 .addReg(ARM::PC)
1324 .addReg(MI->getOperand(0).getReg())
1325 // Add predicate operands.
1326 .addImm(ARMCC::AL)
1327 .addReg(0)
1328 // Add 's' bit operand (always reg0 for this)
1329 .addReg(0));
1330 return;
1331 }
1332 case ARM::BMOVPCB_CALL: {
1333 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
1334 .addReg(ARM::LR)
1335 .addReg(ARM::PC)
1336 // Add predicate operands.
1337 .addImm(ARMCC::AL)
1338 .addReg(0)
1339 // Add 's' bit operand (always reg0 for this)
1340 .addReg(0));
1341
1342 const MachineOperand &Op = MI->getOperand(0);
1343 const GlobalValue *GV = Op.getGlobal();
1344 const unsigned TF = Op.getTargetFlags();
1345 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1346 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1347 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::Bcc)
1348 .addExpr(GVSymExpr)
1349 // Add predicate operands.
1350 .addImm(ARMCC::AL)
1351 .addReg(0));
1352 return;
1353 }
1354 case ARM::MOVi16_ga_pcrel:
1355 case ARM::t2MOVi16_ga_pcrel: {
1356 MCInst TmpInst;
1357 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
1358 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1359
1360 unsigned TF = MI->getOperand(1).getTargetFlags();
1361 const GlobalValue *GV = MI->getOperand(1).getGlobal();
1362 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1363 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1364
1365 MCSymbol *LabelSym =
1366 getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1367 MI->getOperand(2).getImm(), OutContext);
1368 const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
1369 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
1370 const MCExpr *PCRelExpr =
1371 ARMMCExpr::createLower16(MCBinaryExpr::createSub(GVSymExpr,
1372 MCBinaryExpr::createAdd(LabelSymExpr,
1373 MCConstantExpr::create(PCAdj, OutContext),
1374 OutContext), OutContext), OutContext);
1375 TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
1376
1377 // Add predicate operands.
1378 TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1379 TmpInst.addOperand(MCOperand::createReg(0));
1380 // Add 's' bit operand (always reg0 for this)
1381 TmpInst.addOperand(MCOperand::createReg(0));
1382 EmitToStreamer(*OutStreamer, TmpInst);
1383 return;
1384 }
1385 case ARM::MOVTi16_ga_pcrel:
1386 case ARM::t2MOVTi16_ga_pcrel: {
1387 MCInst TmpInst;
1388 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
1389 ? ARM::MOVTi16 : ARM::t2MOVTi16);
1390 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1391 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
1392
1393 unsigned TF = MI->getOperand(2).getTargetFlags();
1394 const GlobalValue *GV = MI->getOperand(2).getGlobal();
1395 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1396 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1397
1398 MCSymbol *LabelSym =
1399 getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1400 MI->getOperand(3).getImm(), OutContext);
1401 const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
1402 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
1403 const MCExpr *PCRelExpr =
1404 ARMMCExpr::createUpper16(MCBinaryExpr::createSub(GVSymExpr,
1405 MCBinaryExpr::createAdd(LabelSymExpr,
1406 MCConstantExpr::create(PCAdj, OutContext),
1407 OutContext), OutContext), OutContext);
1408 TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
1409 // Add predicate operands.
1410 TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1411 TmpInst.addOperand(MCOperand::createReg(0));
1412 // Add 's' bit operand (always reg0 for this)
1413 TmpInst.addOperand(MCOperand::createReg(0));
1414 EmitToStreamer(*OutStreamer, TmpInst);
1415 return;
1416 }
1417 case ARM::tPICADD: {
1418 // This is a pseudo op for a label + instruction sequence, which looks like:
1419 // LPC0:
1420 // add r0, pc
1421 // This adds the address of LPC0 to r0.
1422
1423 // Emit the label.
1424 OutStreamer->EmitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1425 getFunctionNumber(),
1426 MI->getOperand(2).getImm(), OutContext));
1427
1428 // Form and emit the add.
1429 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDhirr)
1430 .addReg(MI->getOperand(0).getReg())
1431 .addReg(MI->getOperand(0).getReg())
1432 .addReg(ARM::PC)
1433 // Add predicate operands.
1434 .addImm(ARMCC::AL)
1435 .addReg(0));
1436 return;
1437 }
1438 case ARM::PICADD: {
1439 // This is a pseudo op for a label + instruction sequence, which looks like:
1440 // LPC0:
1441 // add r0, pc, r0
1442 // This adds the address of LPC0 to r0.
1443
1444 // Emit the label.
1445 OutStreamer->EmitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1446 getFunctionNumber(),
1447 MI->getOperand(2).getImm(), OutContext));
1448
1449 // Form and emit the add.
1450 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDrr)
1451 .addReg(MI->getOperand(0).getReg())
1452 .addReg(ARM::PC)
1453 .addReg(MI->getOperand(1).getReg())
1454 // Add predicate operands.
1455 .addImm(MI->getOperand(3).getImm())
1456 .addReg(MI->getOperand(4).getReg())
1457 // Add 's' bit operand (always reg0 for this)
1458 .addReg(0));
1459 return;
1460 }
1461 case ARM::PICSTR:
1462 case ARM::PICSTRB:
1463 case ARM::PICSTRH:
1464 case ARM::PICLDR:
1465 case ARM::PICLDRB:
1466 case ARM::PICLDRH:
1467 case ARM::PICLDRSB:
1468 case ARM::PICLDRSH: {
1469 // This is a pseudo op for a label + instruction sequence, which looks like:
1470 // LPC0:
1471 // OP r0, [pc, r0]
1472 // The LCP0 label is referenced by a constant pool entry in order to get
1473 // a PC-relative address at the ldr instruction.
1474
1475 // Emit the label.
1476 OutStreamer->EmitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1477 getFunctionNumber(),
1478 MI->getOperand(2).getImm(), OutContext));
1479
1480 // Form and emit the load
1481 unsigned Opcode;
1482 switch (MI->getOpcode()) {
1483 default:
1484 llvm_unreachable("Unexpected opcode!")::llvm::llvm_unreachable_internal("Unexpected opcode!", "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1484)
;
1485 case ARM::PICSTR: Opcode = ARM::STRrs; break;
1486 case ARM::PICSTRB: Opcode = ARM::STRBrs; break;
1487 case ARM::PICSTRH: Opcode = ARM::STRH; break;
1488 case ARM::PICLDR: Opcode = ARM::LDRrs; break;
1489 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break;
1490 case ARM::PICLDRH: Opcode = ARM::LDRH; break;
1491 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1492 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1493 }
1494 EmitToStreamer(*OutStreamer, MCInstBuilder(Opcode)
1495 .addReg(MI->getOperand(0).getReg())
1496 .addReg(ARM::PC)
1497 .addReg(MI->getOperand(1).getReg())
1498 .addImm(0)
1499 // Add predicate operands.
1500 .addImm(MI->getOperand(3).getImm())
1501 .addReg(MI->getOperand(4).getReg()));
1502
1503 return;
1504 }
1505 case ARM::CONSTPOOL_ENTRY: {
1506 if (Subtarget->genExecuteOnly())
1507 llvm_unreachable("execute-only should not generate constant pools")::llvm::llvm_unreachable_internal("execute-only should not generate constant pools"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1507)
;
1508
1509 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1510 /// in the function. The first operand is the ID# for this instruction, the
1511 /// second is the index into the MachineConstantPool that this is, the third
1512 /// is the size in bytes of this constant pool entry.
1513 /// The required alignment is specified on the basic block holding this MI.
1514 unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1515 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
1516
1517 // If this is the first entry of the pool, mark it.
1518 if (!InConstantPool) {
1519 OutStreamer->EmitDataRegion(MCDR_DataRegion);
1520 InConstantPool = true;
1521 }
1522
1523 OutStreamer->EmitLabel(GetCPISymbol(LabelId));
1524
1525 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1526 if (MCPE.isMachineConstantPoolEntry())
1527 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1528 else
1529 EmitGlobalConstant(DL, MCPE.Val.ConstVal);
1530 return;
1531 }
1532 case ARM::JUMPTABLE_ADDRS:
1533 EmitJumpTableAddrs(MI);
1534 return;
1535 case ARM::JUMPTABLE_INSTS:
1536 EmitJumpTableInsts(MI);
1537 return;
1538 case ARM::JUMPTABLE_TBB:
1539 case ARM::JUMPTABLE_TBH:
1540 EmitJumpTableTBInst(MI, MI->getOpcode() == ARM::JUMPTABLE_TBB ? 1 : 2);
1541 return;
1542 case ARM::t2BR_JT: {
1543 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
1544 .addReg(ARM::PC)
1545 .addReg(MI->getOperand(0).getReg())
1546 // Add predicate operands.
1547 .addImm(ARMCC::AL)
1548 .addReg(0));
1549 return;
1550 }
1551 case ARM::t2TBB_JT:
1552 case ARM::t2TBH_JT: {
1553 unsigned Opc = MI->getOpcode() == ARM::t2TBB_JT ? ARM::t2TBB : ARM::t2TBH;
1554 // Lower and emit the PC label, then the instruction itself.
1555 OutStreamer->EmitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
1556 EmitToStreamer(*OutStreamer, MCInstBuilder(Opc)
1557 .addReg(MI->getOperand(0).getReg())
1558 .addReg(MI->getOperand(1).getReg())
1559 // Add predicate operands.
1560 .addImm(ARMCC::AL)
1561 .addReg(0));
1562 return;
1563 }
1564 case ARM::tTBB_JT:
1565 case ARM::tTBH_JT: {
1566
1567 bool Is8Bit = MI->getOpcode() == ARM::tTBB_JT;
1568 unsigned Base = MI->getOperand(0).getReg();
1569 unsigned Idx = MI->getOperand(1).getReg();
1570 assert(MI->getOperand(1).isKill() && "We need the index register as scratch!")(static_cast <bool> (MI->getOperand(1).isKill() &&
"We need the index register as scratch!") ? void (0) : __assert_fail
("MI->getOperand(1).isKill() && \"We need the index register as scratch!\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1570, __extension__ __PRETTY_FUNCTION__))
;
1571
1572 // Multiply up idx if necessary.
1573 if (!Is8Bit)
1574 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLSLri)
1575 .addReg(Idx)
1576 .addReg(ARM::CPSR)
1577 .addReg(Idx)
1578 .addImm(1)
1579 // Add predicate operands.
1580 .addImm(ARMCC::AL)
1581 .addReg(0));
1582
1583 if (Base == ARM::PC) {
1584 // TBB [base, idx] =
1585 // ADDS idx, idx, base
1586 // LDRB idx, [idx, #4] ; or LDRH if TBH
1587 // LSLS idx, #1
1588 // ADDS pc, pc, idx
1589
1590 // When using PC as the base, it's important that there is no padding
1591 // between the last ADDS and the start of the jump table. The jump table
1592 // is 4-byte aligned, so we ensure we're 4 byte aligned here too.
1593 //
1594 // FIXME: Ideally we could vary the LDRB index based on the padding
1595 // between the sequence and jump table, however that relies on MCExprs
1596 // for load indexes which are currently not supported.
1597 OutStreamer->EmitCodeAlignment(4);
1598 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDhirr)
1599 .addReg(Idx)
1600 .addReg(Idx)
1601 .addReg(Base)
1602 // Add predicate operands.
1603 .addImm(ARMCC::AL)
1604 .addReg(0));
1605
1606 unsigned Opc = Is8Bit ? ARM::tLDRBi : ARM::tLDRHi;
1607 EmitToStreamer(*OutStreamer, MCInstBuilder(Opc)
1608 .addReg(Idx)
1609 .addReg(Idx)
1610 .addImm(Is8Bit ? 4 : 2)
1611 // Add predicate operands.
1612 .addImm(ARMCC::AL)
1613 .addReg(0));
1614 } else {
1615 // TBB [base, idx] =
1616 // LDRB idx, [base, idx] ; or LDRH if TBH
1617 // LSLS idx, #1
1618 // ADDS pc, pc, idx
1619
1620 unsigned Opc = Is8Bit ? ARM::tLDRBr : ARM::tLDRHr;
1621 EmitToStreamer(*OutStreamer, MCInstBuilder(Opc)
1622 .addReg(Idx)
1623 .addReg(Base)
1624 .addReg(Idx)
1625 // Add predicate operands.
1626 .addImm(ARMCC::AL)
1627 .addReg(0));
1628 }
1629
1630 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLSLri)
1631 .addReg(Idx)
1632 .addReg(ARM::CPSR)
1633 .addReg(Idx)
1634 .addImm(1)
1635 // Add predicate operands.
1636 .addImm(ARMCC::AL)
1637 .addReg(0));
1638
1639 OutStreamer->EmitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
1640 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDhirr)
1641 .addReg(ARM::PC)
1642 .addReg(ARM::PC)
1643 .addReg(Idx)
1644 // Add predicate operands.
1645 .addImm(ARMCC::AL)
1646 .addReg(0));
1647 return;
1648 }
1649 case ARM::tBR_JTr:
1650 case ARM::BR_JTr: {
1651 // mov pc, target
1652 MCInst TmpInst;
1653 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
1654 ARM::MOVr : ARM::tMOVr;
1655 TmpInst.setOpcode(Opc);
1656 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1657 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1658 // Add predicate operands.
1659 TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1660 TmpInst.addOperand(MCOperand::createReg(0));
1661 // Add 's' bit operand (always reg0 for this)
1662 if (Opc == ARM::MOVr)
1663 TmpInst.addOperand(MCOperand::createReg(0));
1664 EmitToStreamer(*OutStreamer, TmpInst);
1665 return;
1666 }
1667 case ARM::BR_JTm_i12: {
1668 // ldr pc, target
1669 MCInst TmpInst;
1670 TmpInst.setOpcode(ARM::LDRi12);
1671 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1672 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1673 TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
1674 // Add predicate operands.
1675 TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1676 TmpInst.addOperand(MCOperand::createReg(0));
1677 EmitToStreamer(*OutStreamer, TmpInst);
1678 return;
1679 }
1680 case ARM::BR_JTm_rs: {
1681 // ldr pc, target
1682 MCInst TmpInst;
1683 TmpInst.setOpcode(ARM::LDRrs);
1684 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1685 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1686 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
1687 TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
1688 // Add predicate operands.
1689 TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1690 TmpInst.addOperand(MCOperand::createReg(0));
1691 EmitToStreamer(*OutStreamer, TmpInst);
1692 return;
1693 }
1694 case ARM::BR_JTadd: {
1695 // add pc, target, idx
1696 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDrr)
1697 .addReg(ARM::PC)
1698 .addReg(MI->getOperand(0).getReg())
1699 .addReg(MI->getOperand(1).getReg())
1700 // Add predicate operands.
1701 .addImm(ARMCC::AL)
1702 .addReg(0)
1703 // Add 's' bit operand (always reg0 for this)
1704 .addReg(0));
1705 return;
1706 }
1707 case ARM::SPACE:
1708 OutStreamer->EmitZeros(MI->getOperand(1).getImm());
1709 return;
1710 case ARM::TRAP: {
1711 // Non-Darwin binutils don't yet support the "trap" mnemonic.
1712 // FIXME: Remove this special case when they do.
1713 if (!Subtarget->isTargetMachO()) {
1714 uint32_t Val = 0xe7ffdefeUL;
1715 OutStreamer->AddComment("trap");
1716 ATS.emitInst(Val);
1717 return;
1718 }
1719 break;
1720 }
1721 case ARM::TRAPNaCl: {
1722 uint32_t Val = 0xe7fedef0UL;
1723 OutStreamer->AddComment("trap");
1724 ATS.emitInst(Val);
1725 return;
1726 }
1727 case ARM::tTRAP: {
1728 // Non-Darwin binutils don't yet support the "trap" mnemonic.
1729 // FIXME: Remove this special case when they do.
1730 if (!Subtarget->isTargetMachO()) {
1731 uint16_t Val = 0xdefe;
1732 OutStreamer->AddComment("trap");
1733 ATS.emitInst(Val, 'n');
1734 return;
1735 }
1736 break;
1737 }
1738 case ARM::t2Int_eh_sjlj_setjmp:
1739 case ARM::t2Int_eh_sjlj_setjmp_nofp:
1740 case ARM::tInt_eh_sjlj_setjmp: {
1741 // Two incoming args: GPR:$src, GPR:$val
1742 // mov $val, pc
1743 // adds $val, #7
1744 // str $val, [$src, #4]
1745 // movs r0, #0
1746 // b LSJLJEH
1747 // movs r0, #1
1748 // LSJLJEH:
1749 unsigned SrcReg = MI->getOperand(0).getReg();
1750 unsigned ValReg = MI->getOperand(1).getReg();
1751 MCSymbol *Label = OutContext.createTempSymbol("SJLJEH", false, true);
1752 OutStreamer->AddComment("eh_setjmp begin");
1753 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
1754 .addReg(ValReg)
1755 .addReg(ARM::PC)
1756 // Predicate.
1757 .addImm(ARMCC::AL)
1758 .addReg(0));
1759
1760 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDi3)
1761 .addReg(ValReg)
1762 // 's' bit operand
1763 .addReg(ARM::CPSR)
1764 .addReg(ValReg)
1765 .addImm(7)
1766 // Predicate.
1767 .addImm(ARMCC::AL)
1768 .addReg(0));
1769
1770 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tSTRi)
1771 .addReg(ValReg)
1772 .addReg(SrcReg)
1773 // The offset immediate is #4. The operand value is scaled by 4 for the
1774 // tSTR instruction.
1775 .addImm(1)
1776 // Predicate.
1777 .addImm(ARMCC::AL)
1778 .addReg(0));
1779
1780 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVi8)
1781 .addReg(ARM::R0)
1782 .addReg(ARM::CPSR)
1783 .addImm(0)
1784 // Predicate.
1785 .addImm(ARMCC::AL)
1786 .addReg(0));
1787
1788 const MCExpr *SymbolExpr = MCSymbolRefExpr::create(Label, OutContext);
1789 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tB)
1790 .addExpr(SymbolExpr)
1791 .addImm(ARMCC::AL)
1792 .addReg(0));
1793
1794 OutStreamer->AddComment("eh_setjmp end");
1795 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVi8)
1796 .addReg(ARM::R0)
1797 .addReg(ARM::CPSR)
1798 .addImm(1)
1799 // Predicate.
1800 .addImm(ARMCC::AL)
1801 .addReg(0));
1802
1803 OutStreamer->EmitLabel(Label);
1804 return;
1805 }
1806
1807 case ARM::Int_eh_sjlj_setjmp_nofp:
1808 case ARM::Int_eh_sjlj_setjmp: {
1809 // Two incoming args: GPR:$src, GPR:$val
1810 // add $val, pc, #8
1811 // str $val, [$src, #+4]
1812 // mov r0, #0
1813 // add pc, pc, #0
1814 // mov r0, #1
1815 unsigned SrcReg = MI->getOperand(0).getReg();
1816 unsigned ValReg = MI->getOperand(1).getReg();
1817
1818 OutStreamer->AddComment("eh_setjmp begin");
1819 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDri)
1820 .addReg(ValReg)
1821 .addReg(ARM::PC)
1822 .addImm(8)
1823 // Predicate.
1824 .addImm(ARMCC::AL)
1825 .addReg(0)
1826 // 's' bit operand (always reg0 for this).
1827 .addReg(0));
1828
1829 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::STRi12)
1830 .addReg(ValReg)
1831 .addReg(SrcReg)
1832 .addImm(4)
1833 // Predicate.
1834 .addImm(ARMCC::AL)
1835 .addReg(0));
1836
1837 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVi)
1838 .addReg(ARM::R0)
1839 .addImm(0)
1840 // Predicate.
1841 .addImm(ARMCC::AL)
1842 .addReg(0)
1843 // 's' bit operand (always reg0 for this).
1844 .addReg(0));
1845
1846 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDri)
1847 .addReg(ARM::PC)
1848 .addReg(ARM::PC)
1849 .addImm(0)
1850 // Predicate.
1851 .addImm(ARMCC::AL)
1852 .addReg(0)
1853 // 's' bit operand (always reg0 for this).
1854 .addReg(0));
1855
1856 OutStreamer->AddComment("eh_setjmp end");
1857 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVi)
1858 .addReg(ARM::R0)
1859 .addImm(1)
1860 // Predicate.
1861 .addImm(ARMCC::AL)
1862 .addReg(0)
1863 // 's' bit operand (always reg0 for this).
1864 .addReg(0));
1865 return;
1866 }
1867 case ARM::Int_eh_sjlj_longjmp: {
1868 // ldr sp, [$src, #8]
1869 // ldr $scratch, [$src, #4]
1870 // ldr r7, [$src]
1871 // bx $scratch
1872 unsigned SrcReg = MI->getOperand(0).getReg();
1873 unsigned ScratchReg = MI->getOperand(1).getReg();
1874 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1875 .addReg(ARM::SP)
1876 .addReg(SrcReg)
1877 .addImm(8)
1878 // Predicate.
1879 .addImm(ARMCC::AL)
1880 .addReg(0));
1881
1882 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1883 .addReg(ScratchReg)
1884 .addReg(SrcReg)
1885 .addImm(4)
1886 // Predicate.
1887 .addImm(ARMCC::AL)
1888 .addReg(0));
1889
1890 if (STI.isTargetDarwin() || STI.isTargetWindows()) {
1891 // These platforms always use the same frame register
1892 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1893 .addReg(FramePtr)
1894 .addReg(SrcReg)
1895 .addImm(0)
1896 // Predicate.
1897 .addImm(ARMCC::AL)
1898 .addReg(0));
1899 } else {
1900 // If the calling code might use either R7 or R11 as
1901 // frame pointer register, restore it into both.
1902 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1903 .addReg(ARM::R7)
1904 .addReg(SrcReg)
1905 .addImm(0)
1906 // Predicate.
1907 .addImm(ARMCC::AL)
1908 .addReg(0));
1909 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1910 .addReg(ARM::R11)
1911 .addReg(SrcReg)
1912 .addImm(0)
1913 // Predicate.
1914 .addImm(ARMCC::AL)
1915 .addReg(0));
1916 }
1917
1918 assert(Subtarget->hasV4TOps())(static_cast <bool> (Subtarget->hasV4TOps()) ? void (
0) : __assert_fail ("Subtarget->hasV4TOps()", "/build/llvm-toolchain-snapshot-7~svn338205/lib/Target/ARM/ARMAsmPrinter.cpp"
, 1918, __extension__ __PRETTY_FUNCTION__))
;
1919 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
1920 .addReg(ScratchReg)
1921 // Predicate.
1922 .addImm(ARMCC::AL)
1923 .addReg(0));
1924 return;
1925 }
1926 case ARM::tInt_eh_sjlj_longjmp: {
1927 // ldr $scratch, [$src, #8]
1928 // mov sp, $scratch
1929 // ldr $scratch, [$src, #4]
1930 // ldr r7, [$src]
1931 // bx $scratch
1932 unsigned SrcReg = MI->getOperand(0).getReg();
1933 unsigned ScratchReg = MI->getOperand(1).getReg();
1934
1935 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1936 .addReg(ScratchReg)
1937 .addReg(SrcReg)
1938 // The offset immediate is #8. The operand value is scaled by 4 for the
1939 // tLDR instruction.
1940 .addImm(2)
1941 // Predicate.
1942 .addImm(ARMCC::AL)
1943 .addReg(0));
1944
1945 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
1946 .addReg(ARM::SP)
1947 .addReg(ScratchReg)
1948 // Predicate.
1949 .addImm(ARMCC::AL)
1950 .addReg(0));
1951
1952 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1953 .addReg(ScratchReg)
1954 .addReg(SrcReg)
1955 .addImm(1)
1956 // Predicate.
1957 .addImm(ARMCC::AL)
1958 .addReg(0));
1959
1960 if (STI.isTargetDarwin() || STI.isTargetWindows()) {
1961 // These platforms always use the same frame register
1962 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1963 .addReg(FramePtr)
1964 .addReg(SrcReg)
1965 .addImm(0)
1966 // Predicate.
1967 .addImm(ARMCC::AL)
1968 .addReg(0));
1969 } else {
1970 // If the calling code might use either R7 or R11 as
1971 // frame pointer register, restore it into both.
1972 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1973 .addReg(ARM::R7)
1974 .addReg(SrcReg)
1975 .addImm(0)
1976 // Predicate.
1977 .addImm(ARMCC::AL)
1978 .addReg(0));
1979 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1980 .addReg(ARM::R11)
1981 .addReg(SrcReg)
1982 .addImm(0)
1983 // Predicate.
1984 .addImm(ARMCC::AL)
1985 .addReg(0));
1986 }
1987
1988 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tBX)
1989 .addReg(ScratchReg)
1990 // Predicate.
1991 .addImm(ARMCC::AL)
1992 .addReg(0));
1993 return;
1994 }
1995 case ARM::tInt_WIN_eh_sjlj_longjmp: {
1996 // ldr.w r11, [$src, #0]
1997 // ldr.w sp, [$src, #8]
1998 // ldr.w pc, [$src, #4]
1999
2000 unsigned SrcReg = MI->getOperand(0).getReg();
2001
2002 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
2003 .addReg(ARM::R11)
2004 .addReg(SrcReg)
2005 .addImm(0)
2006 // Predicate
2007 .addImm(ARMCC::AL)
2008 .addReg(0));
2009 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
2010 .addReg(ARM::SP)
2011 .addReg(SrcReg)
2012 .addImm(8)
2013 // Predicate
2014 .addImm(ARMCC::AL)
2015 .addReg(0));
2016 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
2017 .addReg(ARM::PC)
2018 .addReg(SrcReg)
2019 .addImm(4)
2020 // Predicate
2021 .addImm(ARMCC::AL)
2022 .addReg(0));
2023 return;
2024 }
2025 case ARM::PATCHABLE_FUNCTION_ENTER:
2026 LowerPATCHABLE_FUNCTION_ENTER(*MI);
2027 return;
2028 case ARM::PATCHABLE_FUNCTION_EXIT:
2029 LowerPATCHABLE_FUNCTION_EXIT(*MI);
2030 return;
2031 case ARM::PATCHABLE_TAIL_CALL:
2032 LowerPATCHABLE_TAIL_CALL(*MI);
2033 return;
2034 }
2035
2036 MCInst TmpInst;
2037 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
2038
2039 EmitToStreamer(*OutStreamer, TmpInst);
2040}
2041
2042//===----------------------------------------------------------------------===//
2043// Target Registry Stuff
2044//===----------------------------------------------------------------------===//
2045
2046// Force static initialization.
2047extern "C" void LLVMInitializeARMAsmPrinter() {
2048 RegisterAsmPrinter<ARMAsmPrinter> X(getTheARMLETarget());
2049 RegisterAsmPrinter<ARMAsmPrinter> Y(getTheARMBETarget());
2050 RegisterAsmPrinter<ARMAsmPrinter> A(getTheThumbLETarget());
2051 RegisterAsmPrinter<ARMAsmPrinter> B(getTheThumbBETarget());
2052}

/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h

1//===- llvm/InlineAsm.h - Class to represent inline asm strings -*- C++ -*-===//
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 class represents the inline asm strings, which are Value*'s that are
11// used as the callee operand of call instructions. InlineAsm's are uniqued
12// like constants, and created via InlineAsm::get(...).
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_IR_INLINEASM_H
17#define LLVM_IR_INLINEASM_H
18
19#include "llvm/ADT/StringRef.h"
20#include "llvm/IR/Value.h"
21#include <cassert>
22#include <string>
23#include <vector>
24
25namespace llvm {
26
27class FunctionType;
28class PointerType;
29template <class ConstantClass> class ConstantUniqueMap;
30
31class InlineAsm final : public Value {
32public:
33 enum AsmDialect {
34 AD_ATT,
35 AD_Intel
36 };
37
38private:
39 friend struct InlineAsmKeyType;
40 friend class ConstantUniqueMap<InlineAsm>;
41
42 std::string AsmString, Constraints;
43 FunctionType *FTy;
44 bool HasSideEffects;
45 bool IsAlignStack;
46 AsmDialect Dialect;
47
48 InlineAsm(FunctionType *Ty, const std::string &AsmString,
49 const std::string &Constraints, bool hasSideEffects,
50 bool isAlignStack, AsmDialect asmDialect);
51
52 /// When the ConstantUniqueMap merges two types and makes two InlineAsms
53 /// identical, it destroys one of them with this method.
54 void destroyConstant();
55
56public:
57 InlineAsm(const InlineAsm &) = delete;
58 InlineAsm &operator=(const InlineAsm &) = delete;
59
60 /// InlineAsm::get - Return the specified uniqued inline asm string.
61 ///
62 static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
63 StringRef Constraints, bool hasSideEffects,
64 bool isAlignStack = false,
65 AsmDialect asmDialect = AD_ATT);
66
67 bool hasSideEffects() const { return HasSideEffects; }
68 bool isAlignStack() const { return IsAlignStack; }
69 AsmDialect getDialect() const { return Dialect; }
70
71 /// getType - InlineAsm's are always pointers.
72 ///
73 PointerType *getType() const {
74 return reinterpret_cast<PointerType*>(Value::getType());
75 }
76
77 /// getFunctionType - InlineAsm's are always pointers to functions.
78 ///
79 FunctionType *getFunctionType() const;
80
81 const std::string &getAsmString() const { return AsmString; }
82 const std::string &getConstraintString() const { return Constraints; }
83
84 /// Verify - This static method can be used by the parser to check to see if
85 /// the specified constraint string is legal for the type. This returns true
86 /// if legal, false if not.
87 ///
88 static bool Verify(FunctionType *Ty, StringRef Constraints);
89
90 // Constraint String Parsing
91 enum ConstraintPrefix {
92 isInput, // 'x'
93 isOutput, // '=x'
94 isClobber // '~x'
95 };
96
97 using ConstraintCodeVector = std::vector<std::string>;
98
99 struct SubConstraintInfo {
100 /// MatchingInput - If this is not -1, this is an output constraint where an
101 /// input constraint is required to match it (e.g. "0"). The value is the
102 /// constraint number that matches this one (for example, if this is
103 /// constraint #0 and constraint #4 has the value "0", this will be 4).
104 int MatchingInput = -1;
105
106 /// Code - The constraint code, either the register name (in braces) or the
107 /// constraint letter/number.
108 ConstraintCodeVector Codes;
109
110 /// Default constructor.
111 SubConstraintInfo() = default;
112 };
113
114 using SubConstraintInfoVector = std::vector<SubConstraintInfo>;
115 struct ConstraintInfo;
116 using ConstraintInfoVector = std::vector<ConstraintInfo>;
117
118 struct ConstraintInfo {
119 /// Type - The basic type of the constraint: input/output/clobber
120 ///
121 ConstraintPrefix Type = isInput;
122
123 /// isEarlyClobber - "&": output operand writes result before inputs are all
124 /// read. This is only ever set for an output operand.
125 bool isEarlyClobber = false;
126
127 /// MatchingInput - If this is not -1, this is an output constraint where an
128 /// input constraint is required to match it (e.g. "0"). The value is the
129 /// constraint number that matches this one (for example, if this is
130 /// constraint #0 and constraint #4 has the value "0", this will be 4).
131 int MatchingInput = -1;
132
133 /// hasMatchingInput - Return true if this is an output constraint that has
134 /// a matching input constraint.
135 bool hasMatchingInput() const { return MatchingInput != -1; }
136
137 /// isCommutative - This is set to true for a constraint that is commutative
138 /// with the next operand.
139 bool isCommutative = false;
140
141 /// isIndirect - True if this operand is an indirect operand. This means
142 /// that the address of the source or destination is present in the call
143 /// instruction, instead of it being returned or passed in explicitly. This
144 /// is represented with a '*' in the asm string.
145 bool isIndirect = false;
146
147 /// Code - The constraint code, either the register name (in braces) or the
148 /// constraint letter/number.
149 ConstraintCodeVector Codes;
150
151 /// isMultipleAlternative - '|': has multiple-alternative constraints.
152 bool isMultipleAlternative = false;
153
154 /// multipleAlternatives - If there are multiple alternative constraints,
155 /// this array will contain them. Otherwise it will be empty.
156 SubConstraintInfoVector multipleAlternatives;
157
158 /// The currently selected alternative constraint index.
159 unsigned currentAlternativeIndex = 0;
160
161 /// Default constructor.
162 ConstraintInfo() = default;
163
164 /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
165 /// fields in this structure. If the constraint string is not understood,
166 /// return true, otherwise return false.
167 bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar);
168
169 /// selectAlternative - Point this constraint to the alternative constraint
170 /// indicated by the index.
171 void selectAlternative(unsigned index);
172 };
173
174 /// ParseConstraints - Split up the constraint string into the specific
175 /// constraints and their prefixes. If this returns an empty vector, and if
176 /// the constraint string itself isn't empty, there was an error parsing.
177 static ConstraintInfoVector ParseConstraints(StringRef ConstraintString);
178
179 /// ParseConstraints - Parse the constraints of this inlineasm object,
180 /// returning them the same way that ParseConstraints(str) does.
181 ConstraintInfoVector ParseConstraints() const {
182 return ParseConstraints(Constraints);
183 }
184
185 // Methods for support type inquiry through isa, cast, and dyn_cast:
186 static bool classof(const Value *V) {
187 return V->getValueID() == Value::InlineAsmVal;
188 }
189
190 // These are helper methods for dealing with flags in the INLINEASM SDNode
191 // in the backend.
192 //
193 // The encoding of the flag word is currently:
194 // Bits 2-0 - A Kind_* value indicating the kind of the operand.
195 // Bits 15-3 - The number of SDNode operands associated with this inline
196 // assembly operand.
197 // If bit 31 is set:
198 // Bit 30-16 - The operand number that this operand must match.
199 // When bits 2-0 are Kind_Mem, the Constraint_* value must be
200 // obtained from the flags for this operand number.
201 // Else if bits 2-0 are Kind_Mem:
202 // Bit 30-16 - A Constraint_* value indicating the original constraint
203 // code.
204 // Else:
205 // Bit 30-16 - The register class ID to use for the operand.
206
207 enum : uint32_t {
208 // Fixed operands on an INLINEASM SDNode.
209 Op_InputChain = 0,
210 Op_AsmString = 1,
211 Op_MDNode = 2,
212 Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack, AsmDialect.
213 Op_FirstOperand = 4,
214
215 // Fixed operands on an INLINEASM MachineInstr.
216 MIOp_AsmString = 0,
217 MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack, AsmDialect.
218 MIOp_FirstOperand = 2,
219
220 // Interpretation of the MIOp_ExtraInfo bit field.
221 Extra_HasSideEffects = 1,
222 Extra_IsAlignStack = 2,
223 Extra_AsmDialect = 4,
224 Extra_MayLoad = 8,
225 Extra_MayStore = 16,
226 Extra_IsConvergent = 32,
227
228 // Inline asm operands map to multiple SDNode / MachineInstr operands.
229 // The first operand is an immediate describing the asm operand, the low
230 // bits is the kind:
231 Kind_RegUse = 1, // Input register, "r".
232 Kind_RegDef = 2, // Output register, "=r".
233 Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
234 Kind_Clobber = 4, // Clobbered register, "~r".
235 Kind_Imm = 5, // Immediate.
236 Kind_Mem = 6, // Memory operand, "m".
237
238 // Memory constraint codes.
239 // These could be tablegenerated but there's little need to do that since
240 // there's plenty of space in the encoding to support the union of all
241 // constraint codes for all targets.
242 Constraint_Unknown = 0,
243 Constraint_es,
244 Constraint_i,
245 Constraint_m,
246 Constraint_o,
247 Constraint_v,
248 Constraint_Q,
249 Constraint_R,
250 Constraint_S,
251 Constraint_T,
252 Constraint_Um,
253 Constraint_Un,
254 Constraint_Uq,
255 Constraint_Us,
256 Constraint_Ut,
257 Constraint_Uv,
258 Constraint_Uy,
259 Constraint_X,
260 Constraint_Z,
261 Constraint_ZC,
262 Constraint_Zy,
263 Constraints_Max = Constraint_Zy,
264 Constraints_ShiftAmount = 16,
265
266 Flag_MatchingOperand = 0x80000000
267 };
268
269 static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
270 assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!")(static_cast <bool> (((NumOps << 3) & ~0xffff
) == 0 && "Too many inline asm operands!") ? void (0)
: __assert_fail ("((NumOps << 3) & ~0xffff) == 0 && \"Too many inline asm operands!\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 270, __extension__ __PRETTY_FUNCTION__))
;
271 assert(Kind >= Kind_RegUse && Kind <= Kind_Mem && "Invalid Kind")(static_cast <bool> (Kind >= Kind_RegUse && Kind
<= Kind_Mem && "Invalid Kind") ? void (0) : __assert_fail
("Kind >= Kind_RegUse && Kind <= Kind_Mem && \"Invalid Kind\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 271, __extension__ __PRETTY_FUNCTION__))
;
272 return Kind | (NumOps << 3);
273 }
274
275 static bool isRegDefKind(unsigned Flag){ return getKind(Flag) == Kind_RegDef;}
276 static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind_Imm; }
277 static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind_Mem; }
278 static bool isRegDefEarlyClobberKind(unsigned Flag) {
279 return getKind(Flag) == Kind_RegDefEarlyClobber;
280 }
281 static bool isClobberKind(unsigned Flag) {
282 return getKind(Flag) == Kind_Clobber;
283 }
284
285 /// getFlagWordForMatchingOp - Augment an existing flag word returned by
286 /// getFlagWord with information indicating that this input operand is tied
287 /// to a previous output operand.
288 static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
289 unsigned MatchedOperandNo) {
290 assert(MatchedOperandNo <= 0x7fff && "Too big matched operand")(static_cast <bool> (MatchedOperandNo <= 0x7fff &&
"Too big matched operand") ? void (0) : __assert_fail ("MatchedOperandNo <= 0x7fff && \"Too big matched operand\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 290, __extension__ __PRETTY_FUNCTION__))
;
291 assert((InputFlag & ~0xffff) == 0 && "High bits already contain data")(static_cast <bool> ((InputFlag & ~0xffff) == 0 &&
"High bits already contain data") ? void (0) : __assert_fail
("(InputFlag & ~0xffff) == 0 && \"High bits already contain data\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 291, __extension__ __PRETTY_FUNCTION__))
;
292 return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
293 }
294
295 /// getFlagWordForRegClass - Augment an existing flag word returned by
296 /// getFlagWord with the required register class for the following register
297 /// operands.
298 /// A tied use operand cannot have a register class, use the register class
299 /// from the def operand instead.
300 static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) {
301 // Store RC + 1, reserve the value 0 to mean 'no register class'.
302 ++RC;
303 assert(!isImmKind(InputFlag) && "Immediates cannot have a register class")(static_cast <bool> (!isImmKind(InputFlag) && "Immediates cannot have a register class"
) ? void (0) : __assert_fail ("!isImmKind(InputFlag) && \"Immediates cannot have a register class\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 303, __extension__ __PRETTY_FUNCTION__))
;
304 assert(!isMemKind(InputFlag) && "Memory operand cannot have a register class")(static_cast <bool> (!isMemKind(InputFlag) && "Memory operand cannot have a register class"
) ? void (0) : __assert_fail ("!isMemKind(InputFlag) && \"Memory operand cannot have a register class\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 304, __extension__ __PRETTY_FUNCTION__))
;
305 assert(RC <= 0x7fff && "Too large register class ID")(static_cast <bool> (RC <= 0x7fff && "Too large register class ID"
) ? void (0) : __assert_fail ("RC <= 0x7fff && \"Too large register class ID\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 305, __extension__ __PRETTY_FUNCTION__))
;
306 assert((InputFlag & ~0xffff) == 0 && "High bits already contain data")(static_cast <bool> ((InputFlag & ~0xffff) == 0 &&
"High bits already contain data") ? void (0) : __assert_fail
("(InputFlag & ~0xffff) == 0 && \"High bits already contain data\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 306, __extension__ __PRETTY_FUNCTION__))
;
307 return InputFlag | (RC << 16);
308 }
309
310 /// Augment an existing flag word returned by getFlagWord with the constraint
311 /// code for a memory constraint.
312 static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint) {
313 assert(isMemKind(InputFlag) && "InputFlag is not a memory constraint!")(static_cast <bool> (isMemKind(InputFlag) && "InputFlag is not a memory constraint!"
) ? void (0) : __assert_fail ("isMemKind(InputFlag) && \"InputFlag is not a memory constraint!\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 313, __extension__ __PRETTY_FUNCTION__))
;
314 assert(Constraint <= 0x7fff && "Too large a memory constraint ID")(static_cast <bool> (Constraint <= 0x7fff &&
"Too large a memory constraint ID") ? void (0) : __assert_fail
("Constraint <= 0x7fff && \"Too large a memory constraint ID\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 314, __extension__ __PRETTY_FUNCTION__))
;
315 assert(Constraint <= Constraints_Max && "Unknown constraint ID")(static_cast <bool> (Constraint <= Constraints_Max &&
"Unknown constraint ID") ? void (0) : __assert_fail ("Constraint <= Constraints_Max && \"Unknown constraint ID\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 315, __extension__ __PRETTY_FUNCTION__))
;
316 assert((InputFlag & ~0xffff) == 0 && "High bits already contain data")(static_cast <bool> ((InputFlag & ~0xffff) == 0 &&
"High bits already contain data") ? void (0) : __assert_fail
("(InputFlag & ~0xffff) == 0 && \"High bits already contain data\""
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 316, __extension__ __PRETTY_FUNCTION__))
;
317 return InputFlag | (Constraint << Constraints_ShiftAmount);
318 }
319
320 static unsigned convertMemFlagWordToMatchingFlagWord(unsigned InputFlag) {
321 assert(isMemKind(InputFlag))(static_cast <bool> (isMemKind(InputFlag)) ? void (0) :
__assert_fail ("isMemKind(InputFlag)", "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 321, __extension__ __PRETTY_FUNCTION__))
;
322 return InputFlag & ~(0x7fff << Constraints_ShiftAmount);
323 }
324
325 static unsigned getKind(unsigned Flags) {
326 return Flags & 7;
327 }
328
329 static unsigned getMemoryConstraintID(unsigned Flag) {
330 assert(isMemKind(Flag))(static_cast <bool> (isMemKind(Flag)) ? void (0) : __assert_fail
("isMemKind(Flag)", "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/IR/InlineAsm.h"
, 330, __extension__ __PRETTY_FUNCTION__))
;
331 return (Flag >> Constraints_ShiftAmount) & 0x7fff;
332 }
333
334 /// getNumOperandRegisters - Extract the number of registers field from the
335 /// inline asm operand flag.
336 static unsigned getNumOperandRegisters(unsigned Flag) {
337 return (Flag & 0xffff) >> 3;
338 }
339
340 /// isUseOperandTiedToDef - Return true if the flag of the inline asm
341 /// operand indicates it is an use operand that's matched to a def operand.
342 static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
343 if ((Flag & Flag_MatchingOperand) == 0)
344 return false;
345 Idx = (Flag & ~Flag_MatchingOperand) >> 16;
346 return true;
347 }
348
349 /// hasRegClassConstraint - Returns true if the flag contains a register
350 /// class constraint. Sets RC to the register class ID.
351 static bool hasRegClassConstraint(unsigned Flag, unsigned &RC) {
352 if (Flag & Flag_MatchingOperand)
13
Taking false branch
353 return false;
354 unsigned High = Flag >> 16;
355 // getFlagWordForRegClass() uses 0 to mean no register class, and otherwise
356 // stores RC + 1.
357 if (!High)
14
Assuming 'High' is 0
15
Taking true branch
358 return false;
16
Returning without writing to 'RC'
359 RC = High - 1;
360 return true;
361 }
362};
363
364} // end namespace llvm
365
366#endif // LLVM_IR_INLINEASM_H