Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/ARM/ARMAsmPrinter.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// | 1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 // | 8 // |
10 // This file contains a printer that converts from our internal representation | 9 // This file contains a printer that converts from our internal representation |
11 // of machine-dependent LLVM code to GAS-format ARM assembly language. | 10 // of machine-dependent LLVM code to GAS-format ARM assembly language. |
16 #include "ARM.h" | 15 #include "ARM.h" |
17 #include "ARMConstantPoolValue.h" | 16 #include "ARMConstantPoolValue.h" |
18 #include "ARMMachineFunctionInfo.h" | 17 #include "ARMMachineFunctionInfo.h" |
19 #include "ARMTargetMachine.h" | 18 #include "ARMTargetMachine.h" |
20 #include "ARMTargetObjectFile.h" | 19 #include "ARMTargetObjectFile.h" |
21 #include "InstPrinter/ARMInstPrinter.h" | |
22 #include "MCTargetDesc/ARMAddressingModes.h" | 20 #include "MCTargetDesc/ARMAddressingModes.h" |
21 #include "MCTargetDesc/ARMInstPrinter.h" | |
23 #include "MCTargetDesc/ARMMCExpr.h" | 22 #include "MCTargetDesc/ARMMCExpr.h" |
23 #include "TargetInfo/ARMTargetInfo.h" | |
24 #include "llvm/ADT/SetVector.h" | 24 #include "llvm/ADT/SetVector.h" |
25 #include "llvm/ADT/SmallString.h" | 25 #include "llvm/ADT/SmallString.h" |
26 #include "llvm/BinaryFormat/COFF.h" | 26 #include "llvm/BinaryFormat/COFF.h" |
27 #include "llvm/CodeGen/MachineFunctionPass.h" | 27 #include "llvm/CodeGen/MachineFunctionPass.h" |
28 #include "llvm/CodeGen/MachineJumpTableInfo.h" | 28 #include "llvm/CodeGen/MachineJumpTableInfo.h" |
115 // Collect all globals that had their storage promoted to a constant pool. | 115 // Collect all globals that had their storage promoted to a constant pool. |
116 // Functions are emitted before variables, so this accumulates promoted | 116 // Functions are emitted before variables, so this accumulates promoted |
117 // globals from all functions in PromotedGlobals. | 117 // globals from all functions in PromotedGlobals. |
118 for (auto *GV : AFI->getGlobalsPromotedToConstantPool()) | 118 for (auto *GV : AFI->getGlobalsPromotedToConstantPool()) |
119 PromotedGlobals.insert(GV); | 119 PromotedGlobals.insert(GV); |
120 | 120 |
121 // Calculate this function's optimization goal. | 121 // Calculate this function's optimization goal. |
122 unsigned OptimizationGoal; | 122 unsigned OptimizationGoal; |
123 if (F.hasFnAttribute(Attribute::OptimizeNone)) | 123 if (F.hasOptNone()) |
124 // For best debugging illusion, speed and small size sacrificed | 124 // For best debugging illusion, speed and small size sacrificed |
125 OptimizationGoal = 6; | 125 OptimizationGoal = 6; |
126 else if (F.optForMinSize()) | 126 else if (F.hasMinSize()) |
127 // Aggressively for small size, speed and debug illusion sacrificed | 127 // Aggressively for small size, speed and debug illusion sacrificed |
128 OptimizationGoal = 4; | 128 OptimizationGoal = 4; |
129 else if (F.optForSize()) | 129 else if (F.hasOptSize()) |
130 // For small size, but speed and debugging illusion preserved | 130 // For small size, but speed and debugging illusion preserved |
131 OptimizationGoal = 3; | 131 OptimizationGoal = 3; |
132 else if (TM.getOptLevel() == CodeGenOpt::Aggressive) | 132 else if (TM.getOptLevel() == CodeGenOpt::Aggressive) |
133 // Aggressively for speed, small size and debug illusion sacrificed | 133 // Aggressively for speed, small size and debug illusion sacrificed |
134 OptimizationGoal = 2; | 134 OptimizationGoal = 2; |
182 | 182 |
183 // We didn't modify anything. | 183 // We didn't modify anything. |
184 return false; | 184 return false; |
185 } | 185 } |
186 | 186 |
187 void ARMAsmPrinter::PrintSymbolOperand(const MachineOperand &MO, | |
188 raw_ostream &O) { | |
189 assert(MO.isGlobal() && "caller should check MO.isGlobal"); | |
190 unsigned TF = MO.getTargetFlags(); | |
191 if (TF & ARMII::MO_LO16) | |
192 O << ":lower16:"; | |
193 else if (TF & ARMII::MO_HI16) | |
194 O << ":upper16:"; | |
195 GetARMGVSymbol(MO.getGlobal(), TF)->print(O, MAI); | |
196 printOffset(MO.getOffset(), O); | |
197 } | |
198 | |
187 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, | 199 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, |
188 raw_ostream &O) { | 200 raw_ostream &O) { |
189 const MachineOperand &MO = MI->getOperand(OpNum); | 201 const MachineOperand &MO = MI->getOperand(OpNum); |
190 unsigned TF = MO.getTargetFlags(); | |
191 | 202 |
192 switch (MO.getType()) { | 203 switch (MO.getType()) { |
193 default: llvm_unreachable("<unknown operand type>"); | 204 default: llvm_unreachable("<unknown operand type>"); |
194 case MachineOperand::MO_Register: { | 205 case MachineOperand::MO_Register: { |
195 unsigned Reg = MO.getReg(); | 206 unsigned Reg = MO.getReg(); |
196 assert(TargetRegisterInfo::isPhysicalRegister(Reg)); | 207 assert(Register::isPhysicalRegister(Reg)); |
197 assert(!MO.getSubReg() && "Subregs should be eliminated!"); | 208 assert(!MO.getSubReg() && "Subregs should be eliminated!"); |
198 if(ARM::GPRPairRegClass.contains(Reg)) { | 209 if(ARM::GPRPairRegClass.contains(Reg)) { |
199 const MachineFunction &MF = *MI->getParent()->getParent(); | 210 const MachineFunction &MF = *MI->getParent()->getParent(); |
200 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); | 211 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
201 Reg = TRI->getSubReg(Reg, ARM::gsub_0); | 212 Reg = TRI->getSubReg(Reg, ARM::gsub_0); |
202 } | 213 } |
203 O << ARMInstPrinter::getRegisterName(Reg); | 214 O << ARMInstPrinter::getRegisterName(Reg); |
204 break; | 215 break; |
205 } | 216 } |
206 case MachineOperand::MO_Immediate: { | 217 case MachineOperand::MO_Immediate: { |
207 int64_t Imm = MO.getImm(); | |
208 O << '#'; | 218 O << '#'; |
219 unsigned TF = MO.getTargetFlags(); | |
209 if (TF == ARMII::MO_LO16) | 220 if (TF == ARMII::MO_LO16) |
210 O << ":lower16:"; | 221 O << ":lower16:"; |
211 else if (TF == ARMII::MO_HI16) | 222 else if (TF == ARMII::MO_HI16) |
212 O << ":upper16:"; | 223 O << ":upper16:"; |
213 O << Imm; | 224 O << MO.getImm(); |
214 break; | 225 break; |
215 } | 226 } |
216 case MachineOperand::MO_MachineBasicBlock: | 227 case MachineOperand::MO_MachineBasicBlock: |
217 MO.getMBB()->getSymbol()->print(O, MAI); | 228 MO.getMBB()->getSymbol()->print(O, MAI); |
218 return; | 229 return; |
219 case MachineOperand::MO_GlobalAddress: { | 230 case MachineOperand::MO_GlobalAddress: { |
220 const GlobalValue *GV = MO.getGlobal(); | 231 PrintSymbolOperand(MO, O); |
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; | 232 break; |
229 } | 233 } |
230 case MachineOperand::MO_ConstantPoolIndex: | 234 case MachineOperand::MO_ConstantPoolIndex: |
231 if (Subtarget->genExecuteOnly()) | 235 if (Subtarget->genExecuteOnly()) |
232 llvm_unreachable("execute-only should not generate constant pools"); | 236 llvm_unreachable("execute-only should not generate constant pools"); |
233 GetCPISymbol(MO.getIndex())->print(O, MAI); | 237 GetCPISymbol(MO.getIndex())->print(O, MAI); |
234 break; | 238 break; |
235 } | 239 } |
240 } | |
241 | |
242 MCSymbol *ARMAsmPrinter::GetCPISymbol(unsigned CPID) const { | |
243 // The AsmPrinter::GetCPISymbol superclass method tries to use CPID as | |
244 // indexes in MachineConstantPool, which isn't in sync with indexes used here. | |
245 const DataLayout &DL = getDataLayout(); | |
246 return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + | |
247 "CPI" + Twine(getFunctionNumber()) + "_" + | |
248 Twine(CPID)); | |
236 } | 249 } |
237 | 250 |
238 //===--------------------------------------------------------------------===// | 251 //===--------------------------------------------------------------------===// |
239 | 252 |
240 MCSymbol *ARMAsmPrinter:: | 253 MCSymbol *ARMAsmPrinter:: |
245 << getFunctionNumber() << '_' << uid; | 258 << getFunctionNumber() << '_' << uid; |
246 return OutContext.getOrCreateSymbol(Name); | 259 return OutContext.getOrCreateSymbol(Name); |
247 } | 260 } |
248 | 261 |
249 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, | 262 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, |
250 unsigned AsmVariant, const char *ExtraCode, | 263 const char *ExtraCode, raw_ostream &O) { |
251 raw_ostream &O) { | |
252 // Does this asm operand have a single letter operand modifier? | 264 // Does this asm operand have a single letter operand modifier? |
253 if (ExtraCode && ExtraCode[0]) { | 265 if (ExtraCode && ExtraCode[0]) { |
254 if (ExtraCode[1] != 0) return true; // Unknown modifier. | 266 if (ExtraCode[1] != 0) return true; // Unknown modifier. |
255 | 267 |
256 switch (ExtraCode[0]) { | 268 switch (ExtraCode[0]) { |
257 default: | 269 default: |
258 // See if this is a generic print operand | 270 // See if this is a generic print operand |
259 return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O); | 271 return AsmPrinter::PrintAsmOperand(MI, OpNum, 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; | |
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. | 272 case 'P': // Print a VFP double precision register. |
274 case 'q': // Print a NEON quad precision register. | 273 case 'q': // Print a NEON quad precision register. |
275 printOperand(MI, OpNum, O); | 274 printOperand(MI, OpNum, O); |
276 return false; | 275 return false; |
277 case 'y': // Print a VFP single precision register as indexed double. | 276 case 'y': // Print a VFP single precision register as indexed double. |
356 OpNum += 1; | 355 OpNum += 1; |
357 } | 356 } |
358 | 357 |
359 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); | 358 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); |
360 unsigned RC; | 359 unsigned RC; |
361 InlineAsm::hasRegClassConstraint(Flags, RC); | 360 bool FirstHalf; |
362 if (RC == ARM::GPRPairRegClassID) { | 361 const ARMBaseTargetMachine &ATM = |
362 static_cast<const ARMBaseTargetMachine &>(TM); | |
363 | |
364 // 'Q' should correspond to the low order register and 'R' to the high | |
365 // order register. Whether this corresponds to the upper or lower half | |
366 // depends on the endianess mode. | |
367 if (ExtraCode[0] == 'Q') | |
368 FirstHalf = ATM.isLittleEndian(); | |
369 else | |
370 // ExtraCode[0] == 'R'. | |
371 FirstHalf = !ATM.isLittleEndian(); | |
372 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); | |
373 if (InlineAsm::hasRegClassConstraint(Flags, RC) && | |
374 ARM::GPRPairRegClass.hasSubClassEq(TRI->getRegClass(RC))) { | |
363 if (NumVals != 1) | 375 if (NumVals != 1) |
364 return true; | 376 return true; |
365 const MachineOperand &MO = MI->getOperand(OpNum); | 377 const MachineOperand &MO = MI->getOperand(OpNum); |
366 if (!MO.isReg()) | 378 if (!MO.isReg()) |
367 return true; | 379 return true; |
368 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); | 380 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); |
369 unsigned Reg = TRI->getSubReg(MO.getReg(), ExtraCode[0] == 'Q' ? | 381 unsigned Reg = TRI->getSubReg(MO.getReg(), FirstHalf ? |
370 ARM::gsub_0 : ARM::gsub_1); | 382 ARM::gsub_0 : ARM::gsub_1); |
371 O << ARMInstPrinter::getRegisterName(Reg); | 383 O << ARMInstPrinter::getRegisterName(Reg); |
372 return false; | 384 return false; |
373 } | 385 } |
374 if (NumVals != 2) | 386 if (NumVals != 2) |
375 return true; | 387 return true; |
376 unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1; | 388 unsigned RegOp = FirstHalf ? OpNum : OpNum + 1; |
377 if (RegOp >= MI->getNumOperands()) | 389 if (RegOp >= MI->getNumOperands()) |
378 return true; | 390 return true; |
379 const MachineOperand &MO = MI->getOperand(RegOp); | 391 const MachineOperand &MO = MI->getOperand(RegOp); |
380 if (!MO.isReg()) | 392 if (!MO.isReg()) |
381 return true; | 393 return true; |
420 printOperand(MI, OpNum, O); | 432 printOperand(MI, OpNum, O); |
421 return false; | 433 return false; |
422 } | 434 } |
423 | 435 |
424 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, | 436 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, |
425 unsigned OpNum, unsigned AsmVariant, | 437 unsigned OpNum, const char *ExtraCode, |
426 const char *ExtraCode, | |
427 raw_ostream &O) { | 438 raw_ostream &O) { |
428 // Does this asm operand have a single letter operand modifier? | 439 // Does this asm operand have a single letter operand modifier? |
429 if (ExtraCode && ExtraCode[0]) { | 440 if (ExtraCode && ExtraCode[0]) { |
430 if (ExtraCode[1] != 0) return true; // Unknown modifier. | 441 if (ExtraCode[1] != 0) return true; // Unknown modifier. |
431 | 442 |
644 ARMBuildAttrs::PositiveZero); | 655 ARMBuildAttrs::PositiveZero); |
645 else if (!TM.Options.UnsafeFPMath) | 656 else if (!TM.Options.UnsafeFPMath) |
646 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, | 657 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, |
647 ARMBuildAttrs::IEEEDenormals); | 658 ARMBuildAttrs::IEEEDenormals); |
648 else { | 659 else { |
649 if (!STI.hasVFP2()) { | 660 if (!STI.hasVFP2Base()) { |
650 // When the target doesn't have an FPU (by design or | 661 // When the target doesn't have an FPU (by design or |
651 // intention), the assumptions made on the software support | 662 // intention), the assumptions made on the software support |
652 // mirror that of the equivalent hardware support *if it | 663 // mirror that of the equivalent hardware support *if it |
653 // existed*. For v7 and better we indicate that denormals are | 664 // existed*. For v7 and better we indicate that denormals are |
654 // flushed preserving sign, and for V6 we indicate that | 665 // flushed preserving sign, and for V6 we indicate that |
655 // denormals are flushed to positive zero. | 666 // denormals are flushed to positive zero. |
656 if (STI.hasV7Ops()) | 667 if (STI.hasV7Ops()) |
657 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, | 668 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, |
658 ARMBuildAttrs::PreserveFPSign); | 669 ARMBuildAttrs::PreserveFPSign); |
659 } else if (STI.hasVFP3()) { | 670 } else if (STI.hasVFP3Base()) { |
660 // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is, | 671 // 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 | 672 // the sign bit of the zero matches the sign bit of the input or |
662 // result that is being flushed to zero. | 673 // result that is being flushed to zero. |
663 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, | 674 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, |
664 ARMBuildAttrs::PreserveFPSign); | 675 ARMBuildAttrs::PreserveFPSign); |
748 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, | 759 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, |
749 ARMBuildAttrs::R9IsGPR); | 760 ARMBuildAttrs::R9IsGPR); |
750 } | 761 } |
751 | 762 |
752 //===----------------------------------------------------------------------===// | 763 //===----------------------------------------------------------------------===// |
764 | |
765 static MCSymbol *getBFLabel(StringRef Prefix, unsigned FunctionNumber, | |
766 unsigned LabelId, MCContext &Ctx) { | |
767 | |
768 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix) | |
769 + "BF" + Twine(FunctionNumber) + "_" + Twine(LabelId)); | |
770 return Label; | |
771 } | |
753 | 772 |
754 static MCSymbol *getPICLabel(StringRef Prefix, unsigned FunctionNumber, | 773 static MCSymbol *getPICLabel(StringRef Prefix, unsigned FunctionNumber, |
755 unsigned LabelId, MCContext &Ctx) { | 774 unsigned LabelId, MCContext &Ctx) { |
756 | 775 |
757 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix) | 776 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix) |
803 return MCSym; | 822 return MCSym; |
804 } else if (Subtarget->isTargetCOFF()) { | 823 } else if (Subtarget->isTargetCOFF()) { |
805 assert(Subtarget->isTargetWindows() && | 824 assert(Subtarget->isTargetWindows() && |
806 "Windows is the only supported COFF target"); | 825 "Windows is the only supported COFF target"); |
807 | 826 |
808 bool IsIndirect = (TargetFlags & ARMII::MO_DLLIMPORT); | 827 bool IsIndirect = |
828 (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB)); | |
809 if (!IsIndirect) | 829 if (!IsIndirect) |
810 return getSymbol(GV); | 830 return getSymbol(GV); |
811 | 831 |
812 SmallString<128> Name; | 832 SmallString<128> Name; |
813 Name = "__imp_"; | 833 if (TargetFlags & ARMII::MO_DLLIMPORT) |
834 Name = "__imp_"; | |
835 else if (TargetFlags & ARMII::MO_COFFSTUB) | |
836 Name = ".refptr."; | |
814 getNameWithPrefix(Name, GV); | 837 getNameWithPrefix(Name, GV); |
815 | 838 |
816 return OutContext.getOrCreateSymbol(Name); | 839 MCSymbol *MCSym = OutContext.getOrCreateSymbol(Name); |
840 | |
841 if (TargetFlags & ARMII::MO_COFFSTUB) { | |
842 MachineModuleInfoCOFF &MMICOFF = | |
843 MMI->getObjFileInfo<MachineModuleInfoCOFF>(); | |
844 MachineModuleInfoImpl::StubValueTy &StubSym = | |
845 MMICOFF.getGVStubEntry(MCSym); | |
846 | |
847 if (!StubSym.getPointer()) | |
848 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV), true); | |
849 } | |
850 | |
851 return MCSym; | |
817 } else if (Subtarget->isTargetELF()) { | 852 } else if (Subtarget->isTargetELF()) { |
818 return getSymbol(GV); | 853 return getSymbol(GV); |
819 } | 854 } |
820 llvm_unreachable("unexpected target"); | 855 llvm_unreachable("unexpected target"); |
821 } | 856 } |
979 const MachineOperand &MO1 = MI->getOperand(1); | 1014 const MachineOperand &MO1 = MI->getOperand(1); |
980 unsigned JTI = MO1.getIndex(); | 1015 unsigned JTI = MO1.getIndex(); |
981 | 1016 |
982 if (Subtarget->isThumb1Only()) | 1017 if (Subtarget->isThumb1Only()) |
983 EmitAlignment(2); | 1018 EmitAlignment(2); |
984 | 1019 |
985 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI); | 1020 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI); |
986 OutStreamer->EmitLabel(JTISymbol); | 1021 OutStreamer->EmitLabel(JTISymbol); |
987 | 1022 |
988 // Emit each entry of the table. | 1023 // Emit each entry of the table. |
989 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); | 1024 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); |
1031 "Only instruction which are involved into frame setup code are allowed"); | 1066 "Only instruction which are involved into frame setup code are allowed"); |
1032 | 1067 |
1033 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer(); | 1068 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer(); |
1034 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); | 1069 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); |
1035 const MachineFunction &MF = *MI->getParent()->getParent(); | 1070 const MachineFunction &MF = *MI->getParent()->getParent(); |
1036 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); | 1071 const TargetRegisterInfo *TargetRegInfo = |
1037 const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); | 1072 MF.getSubtarget().getRegisterInfo(); |
1038 | 1073 const MachineRegisterInfo &MachineRegInfo = MF.getRegInfo(); |
1039 unsigned FramePtr = RegInfo->getFrameRegister(MF); | 1074 |
1075 unsigned FramePtr = TargetRegInfo->getFrameRegister(MF); | |
1040 unsigned Opc = MI->getOpcode(); | 1076 unsigned Opc = MI->getOpcode(); |
1041 unsigned SrcReg, DstReg; | 1077 unsigned SrcReg, DstReg; |
1042 | 1078 |
1043 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { | 1079 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { |
1044 // Two special cases: | 1080 // Two special cases: |
1091 // restored when unwinding, because the function can modify the | 1127 // restored when unwinding, because the function can modify the |
1092 // corresponding stack slots. | 1128 // corresponding stack slots. |
1093 if (MO.isUndef()) { | 1129 if (MO.isUndef()) { |
1094 assert(RegList.empty() && | 1130 assert(RegList.empty() && |
1095 "Pad registers must come before restored ones"); | 1131 "Pad registers must come before restored ones"); |
1096 Pad += 4; | 1132 unsigned Width = |
1133 TargetRegInfo->getRegSizeInBits(MO.getReg(), MachineRegInfo) / 8; | |
1134 Pad += Width; | |
1097 continue; | 1135 continue; |
1098 } | 1136 } |
1099 RegList.push_back(MO.getReg()); | 1137 // Check for registers that are remapped (for a Thumb1 prologue that |
1138 // saves high registers). | |
1139 unsigned Reg = MO.getReg(); | |
1140 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(Reg)) | |
1141 Reg = RemappedReg; | |
1142 RegList.push_back(Reg); | |
1100 } | 1143 } |
1101 break; | 1144 break; |
1102 case ARM::STR_PRE_IMM: | 1145 case ARM::STR_PRE_IMM: |
1103 case ARM::STR_PRE_REG: | 1146 case ARM::STR_PRE_REG: |
1104 case ARM::t2STR_PRE: | 1147 case ARM::t2STR_PRE: |
1144 // Grab the constpool index and check, whether it corresponds to | 1187 // Grab the constpool index and check, whether it corresponds to |
1145 // original or cloned constpool entry. | 1188 // original or cloned constpool entry. |
1146 unsigned CPI = MI->getOperand(1).getIndex(); | 1189 unsigned CPI = MI->getOperand(1).getIndex(); |
1147 const MachineConstantPool *MCP = MF.getConstantPool(); | 1190 const MachineConstantPool *MCP = MF.getConstantPool(); |
1148 if (CPI >= MCP->getConstants().size()) | 1191 if (CPI >= MCP->getConstants().size()) |
1149 CPI = AFI.getOriginalCPIdx(CPI); | 1192 CPI = AFI->getOriginalCPIdx(CPI); |
1150 assert(CPI != -1U && "Invalid constpool index"); | 1193 assert(CPI != -1U && "Invalid constpool index"); |
1151 | 1194 |
1152 // Derive the actual offset. | 1195 // Derive the actual offset. |
1153 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; | 1196 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; |
1154 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); | 1197 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); |
1174 } | 1217 } |
1175 } | 1218 } |
1176 } else if (DstReg == ARM::SP) { | 1219 } else if (DstReg == ARM::SP) { |
1177 MI->print(errs()); | 1220 MI->print(errs()); |
1178 llvm_unreachable("Unsupported opcode for unwinding information"); | 1221 llvm_unreachable("Unsupported opcode for unwinding information"); |
1179 } | 1222 } else if (Opc == ARM::tMOVr) { |
1180 else { | 1223 // If a Thumb1 function spills r8-r11, we copy the values to low |
1224 // registers before pushing them. Record the copy so we can emit the | |
1225 // correct ".save" later. | |
1226 AFI->EHPrologueRemappedRegs[DstReg] = SrcReg; | |
1227 } else { | |
1181 MI->print(errs()); | 1228 MI->print(errs()); |
1182 llvm_unreachable("Unsupported opcode for unwinding information"); | 1229 llvm_unreachable("Unsupported opcode for unwinding information"); |
1183 } | 1230 } |
1184 } | 1231 } |
1185 } | 1232 } |
1401 TmpInst.addOperand(MCOperand::createImm(ARMCC::AL)); | 1448 TmpInst.addOperand(MCOperand::createImm(ARMCC::AL)); |
1402 TmpInst.addOperand(MCOperand::createReg(0)); | 1449 TmpInst.addOperand(MCOperand::createReg(0)); |
1403 // Add 's' bit operand (always reg0 for this) | 1450 // Add 's' bit operand (always reg0 for this) |
1404 TmpInst.addOperand(MCOperand::createReg(0)); | 1451 TmpInst.addOperand(MCOperand::createReg(0)); |
1405 EmitToStreamer(*OutStreamer, TmpInst); | 1452 EmitToStreamer(*OutStreamer, TmpInst); |
1453 return; | |
1454 } | |
1455 case ARM::t2BFi: | |
1456 case ARM::t2BFic: | |
1457 case ARM::t2BFLi: | |
1458 case ARM::t2BFr: | |
1459 case ARM::t2BFLr: { | |
1460 // This is a Branch Future instruction. | |
1461 | |
1462 const MCExpr *BranchLabel = MCSymbolRefExpr::create( | |
1463 getBFLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(), | |
1464 MI->getOperand(0).getIndex(), OutContext), | |
1465 OutContext); | |
1466 | |
1467 auto MCInst = MCInstBuilder(Opc).addExpr(BranchLabel); | |
1468 if (MI->getOperand(1).isReg()) { | |
1469 // For BFr/BFLr | |
1470 MCInst.addReg(MI->getOperand(1).getReg()); | |
1471 } else { | |
1472 // For BFi/BFLi/BFic | |
1473 const MCExpr *BranchTarget; | |
1474 if (MI->getOperand(1).isMBB()) | |
1475 BranchTarget = MCSymbolRefExpr::create( | |
1476 MI->getOperand(1).getMBB()->getSymbol(), OutContext); | |
1477 else if (MI->getOperand(1).isGlobal()) { | |
1478 const GlobalValue *GV = MI->getOperand(1).getGlobal(); | |
1479 BranchTarget = MCSymbolRefExpr::create( | |
1480 GetARMGVSymbol(GV, MI->getOperand(1).getTargetFlags()), OutContext); | |
1481 } else if (MI->getOperand(1).isSymbol()) { | |
1482 BranchTarget = MCSymbolRefExpr::create( | |
1483 GetExternalSymbolSymbol(MI->getOperand(1).getSymbolName()), | |
1484 OutContext); | |
1485 } else | |
1486 llvm_unreachable("Unhandled operand kind in Branch Future instruction"); | |
1487 | |
1488 MCInst.addExpr(BranchTarget); | |
1489 } | |
1490 | |
1491 if (Opc == ARM::t2BFic) { | |
1492 const MCExpr *ElseLabel = MCSymbolRefExpr::create( | |
1493 getBFLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(), | |
1494 MI->getOperand(2).getIndex(), OutContext), | |
1495 OutContext); | |
1496 MCInst.addExpr(ElseLabel); | |
1497 MCInst.addImm(MI->getOperand(3).getImm()); | |
1498 } else { | |
1499 MCInst.addImm(MI->getOperand(2).getImm()) | |
1500 .addReg(MI->getOperand(3).getReg()); | |
1501 } | |
1502 | |
1503 EmitToStreamer(*OutStreamer, MCInst); | |
1504 return; | |
1505 } | |
1506 case ARM::t2BF_LabelPseudo: { | |
1507 // This is a pseudo op for a label used by a branch future instruction | |
1508 | |
1509 // Emit the label. | |
1510 OutStreamer->EmitLabel(getBFLabel(DL.getPrivateGlobalPrefix(), | |
1511 getFunctionNumber(), | |
1512 MI->getOperand(0).getIndex(), OutContext)); | |
1406 return; | 1513 return; |
1407 } | 1514 } |
1408 case ARM::tPICADD: { | 1515 case ARM::tPICADD: { |
1409 // This is a pseudo op for a label + instruction sequence, which looks like: | 1516 // This is a pseudo op for a label + instruction sequence, which looks like: |
1410 // LPC0: | 1517 // LPC0: |