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: