Bug Summary

File:lib/Target/ARM/ARMAsmPrinter.cpp
Warning:line 362, 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~svn325118/build-llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-7~svn325118/lib/Target/ARM -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn325118/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/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/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-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn325118/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-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-14-150435-17243-1 -x c++ /build/llvm-toolchain-snapshot-7~svn325118/lib/Target/ARM/ARMAsmPrinter.cpp

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

/build/llvm-toolchain-snapshot-7~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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~svn325118/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;
359 RC = High - 1;
360 return true;
361 }
362};
363
364} // end namespace llvm
365
366#endif // LLVM_IR_INLINEASM_H