blob: 6d9ad350d459e37556dc560d08c917ad66bacdf2 [file] [log] [blame]
Jason W Kimb3212452010-09-30 02:17:26 +00001//===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
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
Jim Grosbach45e50d82011-08-16 17:06:20 +000010#include "MCTargetDesc/ARMMCTargetDesc.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000011#include "MCTargetDesc/ARMAddressingModes.h"
Joe Abbey8e72eb72014-09-16 09:18:23 +000012#include "MCTargetDesc/ARMAsmBackend.h"
13#include "MCTargetDesc/ARMAsmBackendDarwin.h"
14#include "MCTargetDesc/ARMAsmBackendELF.h"
15#include "MCTargetDesc/ARMAsmBackendWinCOFF.h"
Evan Chengad5f4852011-07-23 00:00:19 +000016#include "MCTargetDesc/ARMBaseInfo.h"
17#include "MCTargetDesc/ARMFixupKinds.h"
Quentin Colombet77ca8b82013-01-14 21:34:09 +000018#include "llvm/ADT/StringSwitch.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000019#include "llvm/MC/MCAsmBackend.h"
Jason W Kimb3212452010-09-30 02:17:26 +000020#include "llvm/MC/MCAssembler.h"
Jim Grosbache78031a2012-04-30 22:30:43 +000021#include "llvm/MC/MCContext.h"
Jim Grosbach87055ed2010-12-08 01:16:55 +000022#include "llvm/MC/MCDirectives.h"
Rafael Espindolaf0e24d42010-12-17 16:59:53 +000023#include "llvm/MC/MCELFObjectWriter.h"
Jason W Kimb3212452010-09-30 02:17:26 +000024#include "llvm/MC/MCExpr.h"
Craig Topper6e80c282012-03-26 06:58:25 +000025#include "llvm/MC/MCFixupKindInfo.h"
Daniel Dunbar73b87132010-12-16 16:08:33 +000026#include "llvm/MC/MCMachObjectWriter.h"
Jason W Kimb3212452010-09-30 02:17:26 +000027#include "llvm/MC/MCObjectWriter.h"
Tim Northoverf8e47e42015-10-28 22:56:36 +000028#include "llvm/MC/MCRegisterInfo.h"
Jason W Kimb3212452010-09-30 02:17:26 +000029#include "llvm/MC/MCSectionELF.h"
30#include "llvm/MC/MCSectionMachO.h"
Jim Grosbach45e50d82011-08-16 17:06:20 +000031#include "llvm/MC/MCSubtargetInfo.h"
Jim Grosbach3b50c9e2012-01-18 00:23:57 +000032#include "llvm/MC/MCValue.h"
Tim Northoverf8e47e42015-10-28 22:56:36 +000033#include "llvm/Support/Debug.h"
Wesley Peck18510902010-10-22 15:52:49 +000034#include "llvm/Support/ELF.h"
Jason W Kimb3212452010-09-30 02:17:26 +000035#include "llvm/Support/ErrorHandling.h"
Tim Northoverf8e47e42015-10-28 22:56:36 +000036#include "llvm/Support/Format.h"
Charles Davis8bdfafd2013-09-01 04:28:48 +000037#include "llvm/Support/MachO.h"
Vedant Kumar366dd9fd2015-08-21 21:52:48 +000038#include "llvm/Support/TargetParser.h"
Jason W Kimb3212452010-09-30 02:17:26 +000039#include "llvm/Support/raw_ostream.h"
Jason W Kimb3212452010-09-30 02:17:26 +000040using namespace llvm;
41
42namespace {
Rafael Espindola6b5e56c2010-12-17 17:45:22 +000043class ARMELFObjectWriter : public MCELFObjectTargetWriter {
44public:
Rafael Espindola1ad40952011-12-21 17:00:36 +000045 ARMELFObjectWriter(uint8_t OSABI)
Joe Abbey8e72eb72014-09-16 09:18:23 +000046 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_ARM,
47 /*HasRelocationAddend*/ false) {}
Rafael Espindola6b5e56c2010-12-17 17:45:22 +000048};
49
Joe Abbey8e72eb72014-09-16 09:18:23 +000050const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
51 const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = {
52 // This table *must* be in the order that the fixup_* kinds are defined in
53 // ARMFixupKinds.h.
54 //
55 // Name Offset (bits) Size (bits) Flags
56 {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
57 {"fixup_t2_ldst_pcrel_12", 0, 32,
58 MCFixupKindInfo::FKF_IsPCRel |
59 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
60 {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
61 {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
62 {"fixup_t2_pcrel_10", 0, 32,
63 MCFixupKindInfo::FKF_IsPCRel |
64 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
Oliver Stannard65b85382016-01-25 10:26:26 +000065 {"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
66 {"fixup_t2_pcrel_9", 0, 32,
67 MCFixupKindInfo::FKF_IsPCRel |
68 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
Joe Abbey8e72eb72014-09-16 09:18:23 +000069 {"fixup_thumb_adr_pcrel_10", 0, 8,
70 MCFixupKindInfo::FKF_IsPCRel |
71 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
72 {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
73 {"fixup_t2_adr_pcrel_12", 0, 32,
74 MCFixupKindInfo::FKF_IsPCRel |
75 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
76 {"fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
77 {"fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
78 {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
79 {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
80 {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
81 {"fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
82 {"fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
83 {"fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
84 {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
85 {"fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
86 {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
87 {"fixup_arm_thumb_cp", 0, 8,
88 MCFixupKindInfo::FKF_IsPCRel |
89 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
90 {"fixup_arm_thumb_bcc", 0, 8, MCFixupKindInfo::FKF_IsPCRel},
91 // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
92 // - 19.
93 {"fixup_arm_movt_hi16", 0, 20, 0},
94 {"fixup_arm_movw_lo16", 0, 20, 0},
95 {"fixup_t2_movt_hi16", 0, 20, 0},
96 {"fixup_t2_movw_lo16", 0, 20, 0},
97 };
98 const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = {
99 // This table *must* be in the order that the fixup_* kinds are defined in
100 // ARMFixupKinds.h.
101 //
102 // Name Offset (bits) Size (bits) Flags
103 {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
104 {"fixup_t2_ldst_pcrel_12", 0, 32,
105 MCFixupKindInfo::FKF_IsPCRel |
106 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
107 {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
108 {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
109 {"fixup_t2_pcrel_10", 0, 32,
110 MCFixupKindInfo::FKF_IsPCRel |
111 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
Oliver Stannard65b85382016-01-25 10:26:26 +0000112 {"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
113 {"fixup_t2_pcrel_9", 0, 32,
114 MCFixupKindInfo::FKF_IsPCRel |
115 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
Joe Abbey8e72eb72014-09-16 09:18:23 +0000116 {"fixup_thumb_adr_pcrel_10", 8, 8,
117 MCFixupKindInfo::FKF_IsPCRel |
118 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
119 {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
120 {"fixup_t2_adr_pcrel_12", 0, 32,
121 MCFixupKindInfo::FKF_IsPCRel |
122 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
123 {"fixup_arm_condbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
124 {"fixup_arm_uncondbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
125 {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
126 {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
127 {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
128 {"fixup_arm_uncondbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
129 {"fixup_arm_condbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
130 {"fixup_arm_blx", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
131 {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
132 {"fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
133 {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
134 {"fixup_arm_thumb_cp", 8, 8,
135 MCFixupKindInfo::FKF_IsPCRel |
136 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
137 {"fixup_arm_thumb_bcc", 8, 8, MCFixupKindInfo::FKF_IsPCRel},
138 // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
139 // - 19.
140 {"fixup_arm_movt_hi16", 12, 20, 0},
141 {"fixup_arm_movw_lo16", 12, 20, 0},
142 {"fixup_t2_movt_hi16", 12, 20, 0},
143 {"fixup_t2_movw_lo16", 12, 20, 0},
144 };
Jim Grosbach45e50d82011-08-16 17:06:20 +0000145
Joe Abbey8e72eb72014-09-16 09:18:23 +0000146 if (Kind < FirstTargetFixupKind)
147 return MCAsmBackend::getFixupKindInfo(Kind);
148
149 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
150 "Invalid kind!");
151 return (IsLittleEndian ? InfosLE : InfosBE)[Kind - FirstTargetFixupKind];
152}
153
154void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) {
155 switch (Flag) {
156 default:
157 break;
158 case MCAF_Code16:
159 setIsThumb(true);
160 break;
161 case MCAF_Code32:
162 setIsThumb(false);
163 break;
Jim Grosbach45e50d82011-08-16 17:06:20 +0000164 }
Joe Abbey8e72eb72014-09-16 09:18:23 +0000165}
Chris Lattner9fdd10d2010-11-17 05:41:32 +0000166} // end anonymous namespace
Jason W Kimb3212452010-09-30 02:17:26 +0000167
Tim Northover42335572015-04-06 18:44:42 +0000168unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const {
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000169 bool HasThumb2 = STI->getFeatureBits()[ARM::FeatureThumb2];
Bradley Smitha1189102016-01-15 10:26:17 +0000170 bool HasV8MBaselineOps = STI->getFeatureBits()[ARM::HasV8MBaselineOps];
Tim Northover42335572015-04-06 18:44:42 +0000171
Jim Grosbach34a7c6d2011-12-05 23:45:46 +0000172 switch (Op) {
Joe Abbey8e72eb72014-09-16 09:18:23 +0000173 default:
174 return Op;
175 case ARM::tBcc:
Aaron Ballmanac336242015-04-07 13:28:37 +0000176 return HasThumb2 ? (unsigned)ARM::t2Bcc : Op;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000177 case ARM::tLDRpci:
Aaron Ballmanac336242015-04-07 13:28:37 +0000178 return HasThumb2 ? (unsigned)ARM::t2LDRpci : Op;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000179 case ARM::tADR:
Aaron Ballmanac336242015-04-07 13:28:37 +0000180 return HasThumb2 ? (unsigned)ARM::t2ADR : Op;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000181 case ARM::tB:
Bradley Smitha1189102016-01-15 10:26:17 +0000182 return HasV8MBaselineOps ? (unsigned)ARM::t2B : Op;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000183 case ARM::tCBZ:
184 return ARM::tHINT;
185 case ARM::tCBNZ:
186 return ARM::tHINT;
Jim Grosbach34a7c6d2011-12-05 23:45:46 +0000187 }
188}
189
Jim Grosbachaba3de92012-01-18 18:52:16 +0000190bool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
Jim Grosbach34a7c6d2011-12-05 23:45:46 +0000191 if (getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode())
192 return true;
Jason W Kimb3212452010-09-30 02:17:26 +0000193 return false;
194}
195
Tim Northover8d67b8e2015-10-02 18:07:18 +0000196const char *ARMAsmBackend::reasonForFixupRelaxation(const MCFixup &Fixup,
197 uint64_t Value) const {
Benjamin Kramer116e99a2012-01-19 21:11:13 +0000198 switch ((unsigned)Fixup.getKind()) {
Jim Grosbachc4aa60f2012-03-19 21:32:32 +0000199 case ARM::fixup_arm_thumb_br: {
200 // Relaxing tB to t2B. tB has a signed 12-bit displacement with the
201 // low bit being an implied zero. There's an implied +4 offset for the
202 // branch, so we adjust the other way here to determine what's
203 // encodable.
204 //
205 // Relax if the value is too big for a (signed) i8.
206 int64_t Offset = int64_t(Value) - 4;
Tim Northover8d67b8e2015-10-02 18:07:18 +0000207 if (Offset > 2046 || Offset < -2048)
208 return "out of range pc-relative fixup value";
209 break;
Jim Grosbachc4aa60f2012-03-19 21:32:32 +0000210 }
Jim Grosbachcb80eb22012-01-18 21:54:16 +0000211 case ARM::fixup_arm_thumb_bcc: {
212 // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the
213 // low bit being an implied zero. There's an implied +4 offset for the
214 // branch, so we adjust the other way here to determine what's
215 // encodable.
216 //
217 // Relax if the value is too big for a (signed) i8.
218 int64_t Offset = int64_t(Value) - 4;
Tim Northover8d67b8e2015-10-02 18:07:18 +0000219 if (Offset > 254 || Offset < -256)
220 return "out of range pc-relative fixup value";
221 break;
Jim Grosbachcb80eb22012-01-18 21:54:16 +0000222 }
Jim Grosbach44e5c392012-01-19 02:09:38 +0000223 case ARM::fixup_thumb_adr_pcrel_10:
Jim Grosbachcb80eb22012-01-18 21:54:16 +0000224 case ARM::fixup_arm_thumb_cp: {
Jim Grosbachb008df42012-01-19 01:50:30 +0000225 // If the immediate is negative, greater than 1020, or not a multiple
226 // of four, the wide version of the instruction must be used.
Jim Grosbachcb80eb22012-01-18 21:54:16 +0000227 int64_t Offset = int64_t(Value) - 4;
Tim Northover8d67b8e2015-10-02 18:07:18 +0000228 if (Offset & 3)
229 return "misaligned pc-relative fixup value";
230 else if (Offset > 1020 || Offset < 0)
231 return "out of range pc-relative fixup value";
232 break;
Jim Grosbachcb80eb22012-01-18 21:54:16 +0000233 }
Tim Northover8d67b8e2015-10-02 18:07:18 +0000234 case ARM::fixup_arm_thumb_cb: {
Kevin Enderby9bd296a2014-01-10 00:43:32 +0000235 // If we have a Thumb CBZ or CBNZ instruction and its target is the next
236 // instruction it is is actually out of range for the instruction.
237 // It will be changed to a NOP.
238 int64_t Offset = (Value & ~1);
Tim Northover8d67b8e2015-10-02 18:07:18 +0000239 if (Offset == 2)
240 return "will be converted to nop";
241 break;
Jim Grosbachcb80eb22012-01-18 21:54:16 +0000242 }
Tim Northover8d67b8e2015-10-02 18:07:18 +0000243 default:
244 llvm_unreachable("Unexpected fixup kind in reasonForFixupRelaxation()!");
245 }
246 return nullptr;
247}
248
249bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
250 const MCRelaxableFragment *DF,
251 const MCAsmLayout &Layout) const {
252 return reasonForFixupRelaxation(Fixup, Value);
Jim Grosbach25b63fa2011-12-06 00:47:03 +0000253}
254
Jim Grosbachaba3de92012-01-18 18:52:16 +0000255void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
Jim Grosbach34a7c6d2011-12-05 23:45:46 +0000256 unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode());
257
258 // Sanity check w/ diagnostic if we get here w/ a bogus instruction.
259 if (RelaxedOp == Inst.getOpcode()) {
260 SmallString<256> Tmp;
261 raw_svector_ostream OS(Tmp);
262 Inst.dump_pretty(OS);
263 OS << "\n";
264 report_fatal_error("unexpected instruction to relax: " + OS.str());
265 }
266
Kevin Enderby9bd296a2014-01-10 00:43:32 +0000267 // If we are changing Thumb CBZ or CBNZ instruction to a NOP, aka tHINT, we
268 // have to change the operands too.
269 if ((Inst.getOpcode() == ARM::tCBZ || Inst.getOpcode() == ARM::tCBNZ) &&
270 RelaxedOp == ARM::tHINT) {
271 Res.setOpcode(RelaxedOp);
Jim Grosbache9119e42015-05-13 18:37:00 +0000272 Res.addOperand(MCOperand::createImm(0));
273 Res.addOperand(MCOperand::createImm(14));
274 Res.addOperand(MCOperand::createReg(0));
Kevin Enderby9bd296a2014-01-10 00:43:32 +0000275 return;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000276 }
Kevin Enderby9bd296a2014-01-10 00:43:32 +0000277
278 // The rest of instructions we're relaxing have the same operands.
Jim Grosbach34a7c6d2011-12-05 23:45:46 +0000279 // We just need to update to the proper opcode.
280 Res = Inst;
281 Res.setOpcode(RelaxedOp);
Jason W Kimb3212452010-09-30 02:17:26 +0000282}
283
Jim Grosbachaba3de92012-01-18 18:52:16 +0000284bool ARMAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
Jim Grosbach45e50d82011-08-16 17:06:20 +0000285 const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8
286 const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP
Joe Abbey8e72eb72014-09-16 09:18:23 +0000287 const uint32_t ARMv4_NopEncoding = 0xe1a00000; // using MOV r0,r0
Jim Grosbach7ccdb7c2011-11-16 22:40:25 +0000288 const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP
Jim Grosbach87055ed2010-12-08 01:16:55 +0000289 if (isThumb()) {
Joe Abbey8e72eb72014-09-16 09:18:23 +0000290 const uint16_t nopEncoding =
291 hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
Jim Grosbach97f1de72010-12-17 19:03:02 +0000292 uint64_t NumNops = Count / 2;
293 for (uint64_t i = 0; i != NumNops; ++i)
Jim Grosbach36e60e92015-06-04 22:24:41 +0000294 OW->write16(nopEncoding);
Jim Grosbach97f1de72010-12-17 19:03:02 +0000295 if (Count & 1)
Jim Grosbach36e60e92015-06-04 22:24:41 +0000296 OW->write8(0);
Jim Grosbach87055ed2010-12-08 01:16:55 +0000297 return true;
298 }
299 // ARM mode
Joe Abbey8e72eb72014-09-16 09:18:23 +0000300 const uint32_t nopEncoding =
301 hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
Jim Grosbach97f1de72010-12-17 19:03:02 +0000302 uint64_t NumNops = Count / 4;
303 for (uint64_t i = 0; i != NumNops; ++i)
Jim Grosbach36e60e92015-06-04 22:24:41 +0000304 OW->write32(nopEncoding);
Jim Grosbach45e50d82011-08-16 17:06:20 +0000305 // FIXME: should this function return false when unable to write exactly
306 // 'Count' bytes with NOP encodings?
Jim Grosbach97f1de72010-12-17 19:03:02 +0000307 switch (Count % 4) {
Joe Abbey8e72eb72014-09-16 09:18:23 +0000308 default:
309 break; // No leftover bytes to write
310 case 1:
Jim Grosbach36e60e92015-06-04 22:24:41 +0000311 OW->write8(0);
Joe Abbey8e72eb72014-09-16 09:18:23 +0000312 break;
313 case 2:
Jim Grosbach36e60e92015-06-04 22:24:41 +0000314 OW->write16(0);
Joe Abbey8e72eb72014-09-16 09:18:23 +0000315 break;
316 case 3:
Jim Grosbach36e60e92015-06-04 22:24:41 +0000317 OW->write16(0);
318 OW->write8(0xa0);
Joe Abbey8e72eb72014-09-16 09:18:23 +0000319 break;
Jim Grosbach97f1de72010-12-17 19:03:02 +0000320 }
321
Rafael Espindola0ed15432010-10-25 17:50:35 +0000322 return true;
Jim Grosbach58bce992010-09-30 03:20:34 +0000323}
Jason W Kimb3212452010-09-30 02:17:26 +0000324
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000325static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian) {
326 if (IsLittleEndian) {
327 // Note that the halfwords are stored high first and low second in thumb;
328 // so we need to swap the fixup value here to map properly.
329 uint32_t Swapped = (Value & 0xFFFF0000) >> 16;
330 Swapped |= (Value & 0x0000FFFF) << 16;
331 return Swapped;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000332 } else
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000333 return Value;
334}
335
336static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf,
337 bool IsLittleEndian) {
338 uint32_t Value;
339
340 if (IsLittleEndian) {
341 Value = (SecondHalf & 0xFFFF) << 16;
342 Value |= (FirstHalf & 0xFFFF);
343 } else {
344 Value = (SecondHalf & 0xFFFF);
345 Value |= (FirstHalf & 0xFFFF) << 16;
346 }
347
348 return Value;
349}
350
Tim Northover8d67b8e2015-10-02 18:07:18 +0000351unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
352 bool IsPCRel, MCContext *Ctx,
353 bool IsLittleEndian,
354 bool IsResolved) const {
Jim Grosbache78031a2012-04-30 22:30:43 +0000355 unsigned Kind = Fixup.getKind();
Jason W Kimfc5c5222010-12-01 22:46:50 +0000356 switch (Kind) {
357 default:
358 llvm_unreachable("Unknown fixup kind!");
Jim Grosbach4416dfa2010-12-17 18:39:10 +0000359 case FK_Data_1:
360 case FK_Data_2:
Jason W Kimfc5c5222010-12-01 22:46:50 +0000361 case FK_Data_4:
Jason W Kimfc5c5222010-12-01 22:46:50 +0000362 return Value;
Saleem Abdulrasoolfc6b85b2014-05-08 01:35:57 +0000363 case FK_SecRel_2:
364 return Value;
Saleem Abdulrasool729c7a02014-05-04 23:13:15 +0000365 case FK_SecRel_4:
366 return Value;
Jason W Kimd5e6e542010-12-03 19:40:23 +0000367 case ARM::fixup_arm_movt_hi16:
Rafael Espindola5904e122014-03-29 06:26:49 +0000368 if (!IsPCRel)
369 Value >>= 16;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000370 // Fallthrough
Rafael Espindola5904e122014-03-29 06:26:49 +0000371 case ARM::fixup_arm_movw_lo16: {
Jason W Kimd5e6e542010-12-03 19:40:23 +0000372 unsigned Hi4 = (Value & 0xF000) >> 12;
373 unsigned Lo12 = Value & 0x0FFF;
374 // inst{19-16} = Hi4;
375 // inst{11-0} = Lo12;
376 Value = (Hi4 << 16) | (Lo12);
377 return Value;
378 }
Evan Chengd4a5c052011-01-14 02:38:49 +0000379 case ARM::fixup_t2_movt_hi16:
Rafael Espindola5904e122014-03-29 06:26:49 +0000380 if (!IsPCRel)
381 Value >>= 16;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000382 // Fallthrough
Rafael Espindola5904e122014-03-29 06:26:49 +0000383 case ARM::fixup_t2_movw_lo16: {
Evan Chengd4a5c052011-01-14 02:38:49 +0000384 unsigned Hi4 = (Value & 0xF000) >> 12;
385 unsigned i = (Value & 0x800) >> 11;
386 unsigned Mid3 = (Value & 0x700) >> 8;
387 unsigned Lo8 = Value & 0x0FF;
388 // inst{19-16} = Hi4;
389 // inst{26} = i;
390 // inst{14-12} = Mid3;
391 // inst{7-0} = Lo8;
Jim Grosbachd76f43e2011-09-30 22:02:45 +0000392 Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000393 return swapHalfWords(Value, IsLittleEndian);
Evan Chengd4a5c052011-01-14 02:38:49 +0000394 }
Owen Anderson3e6ee1d2010-12-09 01:51:07 +0000395 case ARM::fixup_arm_ldst_pcrel_12:
Jason W Kimfc5c5222010-12-01 22:46:50 +0000396 // ARM PC-relative values are offset by 8.
Owen Anderson3ef19d92010-12-09 20:27:52 +0000397 Value -= 4;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000398 // FALLTHROUGH
Owen Anderson3e6ee1d2010-12-09 01:51:07 +0000399 case ARM::fixup_t2_ldst_pcrel_12: {
400 // Offset by 4, adjusted by two due to the half-word ordering of thumb.
Owen Anderson3ef19d92010-12-09 20:27:52 +0000401 Value -= 4;
Owen Anderson3e6ee1d2010-12-09 01:51:07 +0000402 bool isAdd = true;
Jason W Kimfc5c5222010-12-01 22:46:50 +0000403 if ((int64_t)Value < 0) {
404 Value = -Value;
405 isAdd = false;
406 }
Oliver Stannard9be59af2015-11-17 10:00:43 +0000407 if (Ctx && Value >= 4096) {
408 Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
409 return 0;
410 }
Jason W Kimfc5c5222010-12-01 22:46:50 +0000411 Value |= isAdd << 23;
Jim Grosbach3aeb8672010-12-13 19:18:13 +0000412
Owen Anderson3e6ee1d2010-12-09 01:51:07 +0000413 // Same addressing mode as fixup_arm_pcrel_10,
414 // but with 16-bit halfwords swapped.
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000415 if (Kind == ARM::fixup_t2_ldst_pcrel_12)
416 return swapHalfWords(Value, IsLittleEndian);
Jim Grosbach3aeb8672010-12-13 19:18:13 +0000417
Jason W Kimfc5c5222010-12-01 22:46:50 +0000418 return Value;
419 }
Jim Grosbachce2bd8d2010-12-02 00:28:45 +0000420 case ARM::fixup_arm_adr_pcrel_12: {
421 // ARM PC-relative values are offset by 8.
422 Value -= 8;
423 unsigned opc = 4; // bits {24-21}. Default to add: 0b0100
424 if ((int64_t)Value < 0) {
425 Value = -Value;
426 opc = 2; // 0b0010
427 }
Oliver Stannard9be59af2015-11-17 10:00:43 +0000428 if (Ctx && ARM_AM::getSOImmVal(Value) == -1) {
429 Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
430 return 0;
431 }
Jim Grosbachce2bd8d2010-12-02 00:28:45 +0000432 // Encode the immediate and shift the opcode into place.
433 return ARM_AM::getSOImmVal(Value) | (opc << 21);
434 }
Jim Grosbache34793e2010-12-14 16:25:15 +0000435
Owen Anderson6d375e52010-12-14 00:36:49 +0000436 case ARM::fixup_t2_adr_pcrel_12: {
437 Value -= 4;
438 unsigned opc = 0;
439 if ((int64_t)Value < 0) {
440 Value = -Value;
441 opc = 5;
442 }
443
444 uint32_t out = (opc << 21);
Owen Anderson8543d4f2011-03-23 22:03:44 +0000445 out |= (Value & 0x800) << 15;
Owen Anderson6d375e52010-12-14 00:36:49 +0000446 out |= (Value & 0x700) << 4;
447 out |= (Value & 0x0FF);
Jim Grosbache34793e2010-12-14 16:25:15 +0000448
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000449 return swapHalfWords(out, IsLittleEndian);
Owen Anderson6d375e52010-12-14 00:36:49 +0000450 }
Jim Grosbache34793e2010-12-14 16:25:15 +0000451
Jason W Kimd2e2f562011-02-04 19:47:15 +0000452 case ARM::fixup_arm_condbranch:
453 case ARM::fixup_arm_uncondbranch:
James Molloyfb5cd602012-03-30 09:15:32 +0000454 case ARM::fixup_arm_uncondbl:
455 case ARM::fixup_arm_condbl:
Jim Grosbach7b811d32012-02-27 21:36:23 +0000456 case ARM::fixup_arm_blx:
Jason W Kimfc5c5222010-12-01 22:46:50 +0000457 // These values don't encode the low two bits since they're always zero.
458 // Offset by 8 just as above.
Joe Abbey8e72eb72014-09-16 09:18:23 +0000459 if (const MCSymbolRefExpr *SRE =
460 dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000461 if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL)
462 return 0;
Jim Grosbach9e199462010-12-06 23:57:07 +0000463 return 0xffffff & ((Value - 8) >> 2);
Owen Anderson578074b2010-12-13 19:31:11 +0000464 case ARM::fixup_t2_uncondbranch: {
Owen Anderson235c2762010-12-10 23:02:28 +0000465 Value = Value - 4;
Owen Anderson302d5fd2010-12-09 00:27:41 +0000466 Value >>= 1; // Low bit is not encoded.
Jim Grosbach3aeb8672010-12-13 19:18:13 +0000467
Jim Grosbachf588c512010-12-13 19:25:46 +0000468 uint32_t out = 0;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000469 bool I = Value & 0x800000;
Owen Anderson578074b2010-12-13 19:31:11 +0000470 bool J1 = Value & 0x400000;
471 bool J2 = Value & 0x200000;
472 J1 ^= I;
473 J2 ^= I;
Jim Grosbache34793e2010-12-14 16:25:15 +0000474
Joe Abbey8e72eb72014-09-16 09:18:23 +0000475 out |= I << 26; // S bit
476 out |= !J1 << 13; // J1 bit
477 out |= !J2 << 11; // J2 bit
478 out |= (Value & 0x1FF800) << 5; // imm6 field
479 out |= (Value & 0x0007FF); // imm11 field
Jim Grosbache34793e2010-12-14 16:25:15 +0000480
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000481 return swapHalfWords(out, IsLittleEndian);
Owen Anderson578074b2010-12-13 19:31:11 +0000482 }
483 case ARM::fixup_t2_condbranch: {
484 Value = Value - 4;
485 Value >>= 1; // Low bit is not encoded.
Jim Grosbache34793e2010-12-14 16:25:15 +0000486
Owen Anderson578074b2010-12-13 19:31:11 +0000487 uint64_t out = 0;
Owen Anderson14e41272010-12-09 01:02:09 +0000488 out |= (Value & 0x80000) << 7; // S bit
489 out |= (Value & 0x40000) >> 7; // J2 bit
490 out |= (Value & 0x20000) >> 4; // J1 bit
491 out |= (Value & 0x1F800) << 5; // imm6 field
492 out |= (Value & 0x007FF); // imm11 field
Jim Grosbach3aeb8672010-12-13 19:18:13 +0000493
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000494 return swapHalfWords(out, IsLittleEndian);
Owen Anderson302d5fd2010-12-09 00:27:41 +0000495 }
Jim Grosbach9e199462010-12-06 23:57:07 +0000496 case ARM::fixup_arm_thumb_bl: {
Saleem Abdulrasool077fd252014-01-26 22:29:36 +0000497 // The value doesn't encode the low bit (always zero) and is offset by
498 // four. The 32-bit immediate value is encoded as
499 // imm32 = SignExtend(S:I1:I2:imm10:imm11:0)
500 // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
501 // The value is encoded into disjoint bit positions in the destination
502 // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
503 // J = either J1 or J2 bit
504 //
505 // BL: xxxxxSIIIIIIIIII xxJxJIIIIIIIIIII
506 //
507 // Note that the halfwords are stored high first, low second; so we need
508 // to transpose the fixup value here to map properly.
509 uint32_t offset = (Value - 4) >> 1;
510 uint32_t signBit = (offset & 0x800000) >> 23;
511 uint32_t I1Bit = (offset & 0x400000) >> 22;
512 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
513 uint32_t I2Bit = (offset & 0x200000) >> 21;
514 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
515 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
516 uint32_t imm11Bits = (offset & 0x000007FF);
NAKAMURA Takumi8018a292013-06-11 06:52:36 +0000517
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000518 uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
519 uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
Joe Abbey8e72eb72014-09-16 09:18:23 +0000520 (uint16_t)imm11Bits);
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000521 return joinHalfWords(FirstHalf, SecondHalf, IsLittleEndian);
Bill Wendling3392bfc2010-12-09 00:39:08 +0000522 }
523 case ARM::fixup_arm_thumb_blx: {
Saleem Abdulrasool077fd252014-01-26 22:29:36 +0000524 // The value doesn't encode the low two bits (always zero) and is offset by
525 // four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
526 // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
527 // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
528 // The value is encoded into disjoint bit positions in the destination
529 // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
530 // J = either J1 or J2 bit, 0 = zero.
531 //
532 // BLX: xxxxxSIIIIIIIIII xxJxJIIIIIIIIII0
533 //
534 // Note that the halfwords are stored high first, low second; so we need
535 // to transpose the fixup value here to map properly.
536 uint32_t offset = (Value - 2) >> 2;
Joe Abbey8e72eb72014-09-16 09:18:23 +0000537 if (const MCSymbolRefExpr *SRE =
538 dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000539 if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL)
540 offset = 0;
Saleem Abdulrasool077fd252014-01-26 22:29:36 +0000541 uint32_t signBit = (offset & 0x400000) >> 22;
542 uint32_t I1Bit = (offset & 0x200000) >> 21;
543 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
544 uint32_t I2Bit = (offset & 0x100000) >> 20;
545 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
546 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
547 uint32_t imm10LBits = (offset & 0x3FF);
NAKAMURA Takumi8018a292013-06-11 06:52:36 +0000548
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000549 uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
550 uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
Joe Abbey8e72eb72014-09-16 09:18:23 +0000551 ((uint16_t)imm10LBits) << 1);
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000552 return joinHalfWords(FirstHalf, SecondHalf, IsLittleEndian);
Jim Grosbach9e199462010-12-06 23:57:07 +0000553 }
Tim Northover8d67b8e2015-10-02 18:07:18 +0000554 case ARM::fixup_thumb_adr_pcrel_10:
Bill Wendling8a6449c2010-12-08 01:57:09 +0000555 case ARM::fixup_arm_thumb_cp:
Tim Northover8d67b8e2015-10-02 18:07:18 +0000556 // On CPUs supporting Thumb2, this will be relaxed to an ldr.w, otherwise we
557 // could have an error on our hands.
558 if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2] && IsResolved) {
559 const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
Oliver Stannard9be59af2015-11-17 10:00:43 +0000560 if (FixupDiagnostic) {
561 Ctx->reportError(Fixup.getLoc(), FixupDiagnostic);
562 return 0;
563 }
Tim Northover8d67b8e2015-10-02 18:07:18 +0000564 }
565 // Offset by 4, and don't encode the low two bits.
566 return ((Value - 4) >> 2) & 0xff;
Jim Grosbach68b27eb2010-12-09 19:50:12 +0000567 case ARM::fixup_arm_thumb_cb: {
Bill Wendlinga7d6aa92010-12-08 23:01:43 +0000568 // Offset by 4 and don't encode the lower bit, which is always 0.
Tim Northover8d67b8e2015-10-02 18:07:18 +0000569 // FIXME: diagnose if no Thumb2
Bill Wendlinga7d6aa92010-12-08 23:01:43 +0000570 uint32_t Binary = (Value - 4) >> 1;
Owen Andersonf636a642010-12-14 19:42:53 +0000571 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
Bill Wendlinga7d6aa92010-12-08 23:01:43 +0000572 }
Jim Grosbache119da12010-12-10 18:21:33 +0000573 case ARM::fixup_arm_thumb_br:
574 // Offset by 4 and don't encode the lower bit, which is always 0.
Bradley Smitha1189102016-01-15 10:26:17 +0000575 if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2] &&
576 !STI->getFeatureBits()[ARM::HasV8MBaselineOps]) {
Tim Northover8d67b8e2015-10-02 18:07:18 +0000577 const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
Oliver Stannard9be59af2015-11-17 10:00:43 +0000578 if (FixupDiagnostic) {
579 Ctx->reportError(Fixup.getLoc(), FixupDiagnostic);
580 return 0;
581 }
Tim Northover8d67b8e2015-10-02 18:07:18 +0000582 }
Jim Grosbache119da12010-12-10 18:21:33 +0000583 return ((Value - 4) >> 1) & 0x7ff;
Jim Grosbach78485ad2010-12-10 17:13:40 +0000584 case ARM::fixup_arm_thumb_bcc:
585 // Offset by 4 and don't encode the lower bit, which is always 0.
Tim Northover8d67b8e2015-10-02 18:07:18 +0000586 if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2]) {
587 const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
Oliver Stannard9be59af2015-11-17 10:00:43 +0000588 if (FixupDiagnostic) {
589 Ctx->reportError(Fixup.getLoc(), FixupDiagnostic);
590 return 0;
591 }
Tim Northover8d67b8e2015-10-02 18:07:18 +0000592 }
Jim Grosbach78485ad2010-12-10 17:13:40 +0000593 return ((Value - 4) >> 1) & 0xff;
Jim Grosbach8648c102011-12-19 23:06:24 +0000594 case ARM::fixup_arm_pcrel_10_unscaled: {
595 Value = Value - 8; // ARM fixups offset by an additional word and don't
596 // need to adjust for the half-word ordering.
597 bool isAdd = true;
598 if ((int64_t)Value < 0) {
599 Value = -Value;
600 isAdd = false;
601 }
Jim Grosbach913cc302012-03-30 21:54:22 +0000602 // The value has the low 4 bits encoded in [3:0] and the high 4 in [11:8].
Oliver Stannard9be59af2015-11-17 10:00:43 +0000603 if (Ctx && Value >= 256) {
604 Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
605 return 0;
606 }
Jim Grosbach913cc302012-03-30 21:54:22 +0000607 Value = (Value & 0xf) | ((Value & 0xf0) << 4);
Jim Grosbach8648c102011-12-19 23:06:24 +0000608 return Value | (isAdd << 23);
609 }
Jim Grosbach3c685612010-12-08 20:32:07 +0000610 case ARM::fixup_arm_pcrel_10:
Owen Anderson4743d752010-12-10 22:46:47 +0000611 Value = Value - 4; // ARM fixups offset by an additional word and don't
Jim Grosbach3c685612010-12-08 20:32:07 +0000612 // need to adjust for the half-word ordering.
Joe Abbey8e72eb72014-09-16 09:18:23 +0000613 // Fall through.
Jim Grosbach3c685612010-12-08 20:32:07 +0000614 case ARM::fixup_t2_pcrel_10: {
615 // Offset by 4, adjusted by two due to the half-word ordering of thumb.
Owen Anderson4743d752010-12-10 22:46:47 +0000616 Value = Value - 4;
Jason W Kimfc5c5222010-12-01 22:46:50 +0000617 bool isAdd = true;
618 if ((int64_t)Value < 0) {
619 Value = -Value;
620 isAdd = false;
621 }
622 // These values don't encode the low two bits since they're always zero.
623 Value >>= 2;
Oliver Stannard9be59af2015-11-17 10:00:43 +0000624 if (Ctx && Value >= 256) {
625 Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
626 return 0;
627 }
Jason W Kimfc5c5222010-12-01 22:46:50 +0000628 Value |= isAdd << 23;
Jim Grosbach3c685612010-12-08 20:32:07 +0000629
Jim Grosbach8648c102011-12-19 23:06:24 +0000630 // Same addressing mode as fixup_arm_pcrel_10, but with 16-bit halfwords
631 // swapped.
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000632 if (Kind == ARM::fixup_t2_pcrel_10)
633 return swapHalfWords(Value, IsLittleEndian);
Jim Grosbach3c685612010-12-08 20:32:07 +0000634
Jason W Kimfc5c5222010-12-01 22:46:50 +0000635 return Value;
636 }
Oliver Stannard65b85382016-01-25 10:26:26 +0000637 case ARM::fixup_arm_pcrel_9:
638 Value = Value - 4; // ARM fixups offset by an additional word and don't
639 // need to adjust for the half-word ordering.
640 // Fall through.
641 case ARM::fixup_t2_pcrel_9: {
642 // Offset by 4, adjusted by two due to the half-word ordering of thumb.
643 Value = Value - 4;
644 bool isAdd = true;
645 if ((int64_t)Value < 0) {
646 Value = -Value;
647 isAdd = false;
648 }
649 // These values don't encode the low bit since it's always zero.
650 if (Ctx && (Value & 1)) {
651 Ctx->reportError(Fixup.getLoc(), "invalid value for this fixup");
652 return 0;
653 }
654 Value >>= 1;
655 if (Ctx && Value >= 256) {
656 Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
657 return 0;
658 }
659 Value |= isAdd << 23;
660
661 // Same addressing mode as fixup_arm_pcrel_9, but with 16-bit halfwords
662 // swapped.
663 if (Kind == ARM::fixup_t2_pcrel_9)
664 return swapHalfWords(Value, IsLittleEndian);
665
666 return Value;
667 }
Jason W Kimfc5c5222010-12-01 22:46:50 +0000668 }
669}
670
Jim Grosbache78031a2012-04-30 22:30:43 +0000671void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,
672 const MCAsmLayout &Layout,
673 const MCFixup &Fixup,
674 const MCFragment *DF,
Rafael Espindola3e3de5e2014-03-28 16:06:09 +0000675 const MCValue &Target, uint64_t &Value,
Jim Grosbache78031a2012-04-30 22:30:43 +0000676 bool &IsResolved) {
677 const MCSymbolRefExpr *A = Target.getSymA();
Rafael Espindola49b85482015-11-04 23:00:39 +0000678 const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
Jim Grosbache78031a2012-04-30 22:30:43 +0000679 // Some fixups to thumb function symbols need the low bit (thumb bit)
680 // twiddled.
681 if ((unsigned)Fixup.getKind() != ARM::fixup_arm_ldst_pcrel_12 &&
682 (unsigned)Fixup.getKind() != ARM::fixup_t2_ldst_pcrel_12 &&
683 (unsigned)Fixup.getKind() != ARM::fixup_arm_adr_pcrel_12 &&
684 (unsigned)Fixup.getKind() != ARM::fixup_thumb_adr_pcrel_10 &&
685 (unsigned)Fixup.getKind() != ARM::fixup_t2_adr_pcrel_12 &&
686 (unsigned)Fixup.getKind() != ARM::fixup_arm_thumb_cp) {
Rafael Espindola49b85482015-11-04 23:00:39 +0000687 if (Sym) {
688 if (Asm.isThumbFunc(Sym))
Jim Grosbache78031a2012-04-30 22:30:43 +0000689 Value |= 1;
690 }
691 }
Rafael Espindola49b85482015-11-04 23:00:39 +0000692 if (IsResolved && (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) {
693 assert(Sym && "How did we resolve this?");
694
695 // If the symbol is external the linker will handle it.
696 // FIXME: Should we handle it as an optimization?
Rafael Espindolae61a9022015-11-05 01:10:15 +0000697
698 // If the symbol is out of range, produce a relocation and hope the
699 // linker can handle it. GNU AS produces an error in this case.
700 if (Sym->isExternal() || Value >= 0x400004)
Rafael Espindola49b85482015-11-04 23:00:39 +0000701 IsResolved = false;
Logan Chiend5c48aa2014-02-05 14:15:16 +0000702 }
Jim Grosbache78031a2012-04-30 22:30:43 +0000703 // We must always generate a relocation for BL/BLX instructions if we have
704 // a symbol to reference, as the linker relies on knowing the destination
705 // symbol's thumb-ness to get interworking right.
706 if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx ||
Jim Grosbache78031a2012-04-30 22:30:43 +0000707 (unsigned)Fixup.getKind() == ARM::fixup_arm_blx ||
708 (unsigned)Fixup.getKind() == ARM::fixup_arm_uncondbl ||
709 (unsigned)Fixup.getKind() == ARM::fixup_arm_condbl))
710 IsResolved = false;
711
712 // Try to get the encoded value for the fixup as-if we're mapping it into
713 // the instruction. This allows adjustFixupValue() to issue a diagnostic
714 // if the value aren't invalid.
Christian Pirkerfdce7ce2014-05-06 10:05:11 +0000715 (void)adjustFixupValue(Fixup, Value, false, &Asm.getContext(),
Tim Northover8d67b8e2015-10-02 18:07:18 +0000716 IsLittleEndian, IsResolved);
Jim Grosbache78031a2012-04-30 22:30:43 +0000717}
718
Bill Wendlingf09c44c2010-12-07 23:11:00 +0000719/// getFixupKindNumBytes - The number of bytes the fixup may change.
Jim Grosbach9d6d77a2010-11-11 18:04:49 +0000720static unsigned getFixupKindNumBytes(unsigned Kind) {
Jim Grosbach90987142010-11-09 01:37:15 +0000721 switch (Kind) {
Jim Grosbach9e199462010-12-06 23:57:07 +0000722 default:
723 llvm_unreachable("Unknown fixup kind!");
Bill Wendling8a6449c2010-12-08 01:57:09 +0000724
Jim Grosbach4416dfa2010-12-17 18:39:10 +0000725 case FK_Data_1:
Jim Grosbach78485ad2010-12-10 17:13:40 +0000726 case ARM::fixup_arm_thumb_bcc:
Bill Wendling8a6449c2010-12-08 01:57:09 +0000727 case ARM::fixup_arm_thumb_cp:
Jim Grosbach509dc2a2010-12-14 22:28:03 +0000728 case ARM::fixup_thumb_adr_pcrel_10:
Bill Wendling8a6449c2010-12-08 01:57:09 +0000729 return 1;
730
Jim Grosbach4416dfa2010-12-17 18:39:10 +0000731 case FK_Data_2:
Jim Grosbache119da12010-12-10 18:21:33 +0000732 case ARM::fixup_arm_thumb_br:
Jim Grosbach68b27eb2010-12-09 19:50:12 +0000733 case ARM::fixup_arm_thumb_cb:
Bill Wendlinga7d6aa92010-12-08 23:01:43 +0000734 return 2;
735
Jim Grosbach8648c102011-12-19 23:06:24 +0000736 case ARM::fixup_arm_pcrel_10_unscaled:
Jim Grosbach9e199462010-12-06 23:57:07 +0000737 case ARM::fixup_arm_ldst_pcrel_12:
738 case ARM::fixup_arm_pcrel_10:
Oliver Stannard65b85382016-01-25 10:26:26 +0000739 case ARM::fixup_arm_pcrel_9:
Jim Grosbach9e199462010-12-06 23:57:07 +0000740 case ARM::fixup_arm_adr_pcrel_12:
James Molloyfb5cd602012-03-30 09:15:32 +0000741 case ARM::fixup_arm_uncondbl:
742 case ARM::fixup_arm_condbl:
Jim Grosbach7b811d32012-02-27 21:36:23 +0000743 case ARM::fixup_arm_blx:
Jason W Kimd2e2f562011-02-04 19:47:15 +0000744 case ARM::fixup_arm_condbranch:
745 case ARM::fixup_arm_uncondbranch:
Jim Grosbach9e199462010-12-06 23:57:07 +0000746 return 3;
Bill Wendling8a6449c2010-12-08 01:57:09 +0000747
748 case FK_Data_4:
Owen Anderson3e6ee1d2010-12-09 01:51:07 +0000749 case ARM::fixup_t2_ldst_pcrel_12:
Owen Anderson578074b2010-12-13 19:31:11 +0000750 case ARM::fixup_t2_condbranch:
751 case ARM::fixup_t2_uncondbranch:
Owen Anderson0f7142d2010-12-08 00:18:36 +0000752 case ARM::fixup_t2_pcrel_10:
Oliver Stannard65b85382016-01-25 10:26:26 +0000753 case ARM::fixup_t2_pcrel_9:
Owen Anderson6d375e52010-12-14 00:36:49 +0000754 case ARM::fixup_t2_adr_pcrel_12:
Jim Grosbach9e199462010-12-06 23:57:07 +0000755 case ARM::fixup_arm_thumb_bl:
Bill Wendling3392bfc2010-12-09 00:39:08 +0000756 case ARM::fixup_arm_thumb_blx:
Evan Chengd4a5c052011-01-14 02:38:49 +0000757 case ARM::fixup_arm_movt_hi16:
758 case ARM::fixup_arm_movw_lo16:
Evan Chengd4a5c052011-01-14 02:38:49 +0000759 case ARM::fixup_t2_movt_hi16:
760 case ARM::fixup_t2_movw_lo16:
Jim Grosbach9e199462010-12-06 23:57:07 +0000761 return 4;
Saleem Abdulrasool729c7a02014-05-04 23:13:15 +0000762
Saleem Abdulrasoolfc6b85b2014-05-08 01:35:57 +0000763 case FK_SecRel_2:
764 return 2;
Saleem Abdulrasool729c7a02014-05-04 23:13:15 +0000765 case FK_SecRel_4:
766 return 4;
Jim Grosbach90987142010-11-09 01:37:15 +0000767 }
768}
769
Christian Pirker2a111602014-03-28 14:35:30 +0000770/// getFixupKindContainerSizeBytes - The number of bytes of the
771/// container involved in big endian.
772static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
773 switch (Kind) {
774 default:
775 llvm_unreachable("Unknown fixup kind!");
776
777 case FK_Data_1:
778 return 1;
779 case FK_Data_2:
780 return 2;
781 case FK_Data_4:
782 return 4;
783
784 case ARM::fixup_arm_thumb_bcc:
785 case ARM::fixup_arm_thumb_cp:
786 case ARM::fixup_thumb_adr_pcrel_10:
787 case ARM::fixup_arm_thumb_br:
788 case ARM::fixup_arm_thumb_cb:
789 // Instruction size is 2 bytes.
790 return 2;
791
792 case ARM::fixup_arm_pcrel_10_unscaled:
793 case ARM::fixup_arm_ldst_pcrel_12:
794 case ARM::fixup_arm_pcrel_10:
795 case ARM::fixup_arm_adr_pcrel_12:
796 case ARM::fixup_arm_uncondbl:
797 case ARM::fixup_arm_condbl:
798 case ARM::fixup_arm_blx:
799 case ARM::fixup_arm_condbranch:
800 case ARM::fixup_arm_uncondbranch:
801 case ARM::fixup_t2_ldst_pcrel_12:
802 case ARM::fixup_t2_condbranch:
803 case ARM::fixup_t2_uncondbranch:
804 case ARM::fixup_t2_pcrel_10:
805 case ARM::fixup_t2_adr_pcrel_12:
806 case ARM::fixup_arm_thumb_bl:
807 case ARM::fixup_arm_thumb_blx:
808 case ARM::fixup_arm_movt_hi16:
809 case ARM::fixup_arm_movw_lo16:
Christian Pirker2a111602014-03-28 14:35:30 +0000810 case ARM::fixup_t2_movt_hi16:
811 case ARM::fixup_t2_movw_lo16:
Christian Pirker2a111602014-03-28 14:35:30 +0000812 // Instruction size is 4 bytes.
813 return 4;
814 }
815}
816
Benjamin Kramer07ea85a2012-11-24 14:36:43 +0000817void ARMAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
Rafael Espindola5904e122014-03-29 06:26:49 +0000818 unsigned DataSize, uint64_t Value,
819 bool IsPCRel) const {
Jim Grosbach9d6d77a2010-11-11 18:04:49 +0000820 unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
Tim Northover8d67b8e2015-10-02 18:07:18 +0000821 Value =
822 adjustFixupValue(Fixup, Value, IsPCRel, nullptr, IsLittleEndian, true);
Joe Abbey8e72eb72014-09-16 09:18:23 +0000823 if (!Value)
824 return; // Doesn't change encoding.
Jim Grosbach90987142010-11-09 01:37:15 +0000825
Bill Wendlingf09c44c2010-12-07 23:11:00 +0000826 unsigned Offset = Fixup.getOffset();
827 assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!");
828
Christian Pirker2a111602014-03-28 14:35:30 +0000829 // Used to point to big endian bytes.
830 unsigned FullSizeBytes;
Christian Pirker875629f2014-05-20 09:24:37 +0000831 if (!IsLittleEndian) {
Christian Pirker2a111602014-03-28 14:35:30 +0000832 FullSizeBytes = getFixupKindContainerSizeBytes(Fixup.getKind());
Christian Pirker875629f2014-05-20 09:24:37 +0000833 assert((Offset + FullSizeBytes) <= DataSize && "Invalid fixup size!");
834 assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
835 }
Christian Pirker2a111602014-03-28 14:35:30 +0000836
Benjamin Kramer07ea85a2012-11-24 14:36:43 +0000837 // For each byte of the fragment that the fixup touches, mask in the bits from
838 // the fixup value. The Value has been "split up" into the appropriate
839 // bitfields above.
Christian Pirker2a111602014-03-28 14:35:30 +0000840 for (unsigned i = 0; i != NumBytes; ++i) {
841 unsigned Idx = IsLittleEndian ? i : (FullSizeBytes - 1 - i);
842 Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
843 }
Jason W Kimb3212452010-09-30 02:17:26 +0000844}
Bill Wendling721724e2010-12-07 23:05:20 +0000845
Tim Northoverf8e47e42015-10-28 22:56:36 +0000846namespace CU {
847
848/// \brief Compact unwind encoding values.
849enum CompactUnwindEncodings {
850 UNWIND_ARM_MODE_MASK = 0x0F000000,
851 UNWIND_ARM_MODE_FRAME = 0x01000000,
852 UNWIND_ARM_MODE_FRAME_D = 0x02000000,
853 UNWIND_ARM_MODE_DWARF = 0x04000000,
854
855 UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
856
857 UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
858 UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
859 UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
860
861 UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
862 UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
863 UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
864 UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
865 UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
866
867 UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000F00,
868
869 UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF
870};
871
872} // end CU namespace
873
874/// Generate compact unwind encoding for the function based on the CFI
875/// instructions. If the CFI instructions describe a frame that cannot be
876/// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
877/// tells the runtime to fallback and unwind using dwarf.
878uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
879 ArrayRef<MCCFIInstruction> Instrs) const {
880 DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n");
881 // Only armv7k uses CFI based unwinding.
882 if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K)
883 return 0;
884 // No .cfi directives means no frame.
885 if (Instrs.empty())
886 return 0;
887 // Start off assuming CFA is at SP+0.
888 int CFARegister = ARM::SP;
889 int CFARegisterOffset = 0;
890 // Mark savable registers as initially unsaved
891 DenseMap<unsigned, int> RegOffsets;
892 int FloatRegCount = 0;
893 // Process each .cfi directive and build up compact unwind info.
894 for (size_t i = 0, e = Instrs.size(); i != e; ++i) {
895 int Reg;
896 const MCCFIInstruction &Inst = Instrs[i];
897 switch (Inst.getOperation()) {
898 case MCCFIInstruction::OpDefCfa: // DW_CFA_def_cfa
899 CFARegisterOffset = -Inst.getOffset();
900 CFARegister = MRI.getLLVMRegNum(Inst.getRegister(), true);
901 break;
902 case MCCFIInstruction::OpDefCfaOffset: // DW_CFA_def_cfa_offset
903 CFARegisterOffset = -Inst.getOffset();
904 break;
905 case MCCFIInstruction::OpDefCfaRegister: // DW_CFA_def_cfa_register
906 CFARegister = MRI.getLLVMRegNum(Inst.getRegister(), true);
907 break;
908 case MCCFIInstruction::OpOffset: // DW_CFA_offset
909 Reg = MRI.getLLVMRegNum(Inst.getRegister(), true);
910 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
911 RegOffsets[Reg] = Inst.getOffset();
912 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
913 RegOffsets[Reg] = Inst.getOffset();
914 ++FloatRegCount;
915 } else {
916 DEBUG_WITH_TYPE("compact-unwind",
917 llvm::dbgs() << ".cfi_offset on unknown register="
918 << Inst.getRegister() << "\n");
919 return CU::UNWIND_ARM_MODE_DWARF;
920 }
921 break;
922 case MCCFIInstruction::OpRelOffset: // DW_CFA_advance_loc
923 // Ignore
924 break;
925 default:
926 // Directive not convertable to compact unwind, bail out.
927 DEBUG_WITH_TYPE("compact-unwind",
928 llvm::dbgs()
929 << "CFI directive not compatiable with comact "
930 "unwind encoding, opcode=" << Inst.getOperation()
931 << "\n");
932 return CU::UNWIND_ARM_MODE_DWARF;
933 break;
934 }
935 }
936
937 // If no frame set up, return no unwind info.
938 if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
939 return 0;
940
941 // Verify standard frame (lr/r7) was used.
942 if (CFARegister != ARM::R7) {
943 DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "frame register is "
944 << CFARegister
945 << " instead of r7\n");
946 return CU::UNWIND_ARM_MODE_DWARF;
947 }
948 int StackAdjust = CFARegisterOffset - 8;
949 if (RegOffsets.lookup(ARM::LR) != (-4 - StackAdjust)) {
950 DEBUG_WITH_TYPE("compact-unwind",
951 llvm::dbgs()
952 << "LR not saved as standard frame, StackAdjust="
953 << StackAdjust
954 << ", CFARegisterOffset=" << CFARegisterOffset
955 << ", lr save at offset=" << RegOffsets[14] << "\n");
956 return CU::UNWIND_ARM_MODE_DWARF;
957 }
958 if (RegOffsets.lookup(ARM::R7) != (-8 - StackAdjust)) {
959 DEBUG_WITH_TYPE("compact-unwind",
960 llvm::dbgs() << "r7 not saved as standard frame\n");
961 return CU::UNWIND_ARM_MODE_DWARF;
962 }
963 uint32_t CompactUnwindEncoding = CU::UNWIND_ARM_MODE_FRAME;
964
965 // If var-args are used, there may be a stack adjust required.
966 switch (StackAdjust) {
967 case 0:
968 break;
969 case 4:
970 CompactUnwindEncoding |= 0x00400000;
971 break;
972 case 8:
973 CompactUnwindEncoding |= 0x00800000;
974 break;
975 case 12:
976 CompactUnwindEncoding |= 0x00C00000;
977 break;
978 default:
979 DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs()
980 << ".cfi_def_cfa stack adjust ("
981 << StackAdjust << ") out of range\n");
982 return CU::UNWIND_ARM_MODE_DWARF;
983 }
984
985 // If r6 is saved, it must be right below r7.
986 static struct {
987 unsigned Reg;
988 unsigned Encoding;
989 } GPRCSRegs[] = {{ARM::R6, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R6},
990 {ARM::R5, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R5},
991 {ARM::R4, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R4},
992 {ARM::R12, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R12},
993 {ARM::R11, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R11},
994 {ARM::R10, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R10},
995 {ARM::R9, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R9},
996 {ARM::R8, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R8}};
997
998 int CurOffset = -8 - StackAdjust;
999 for (auto CSReg : GPRCSRegs) {
1000 auto Offset = RegOffsets.find(CSReg.Reg);
1001 if (Offset == RegOffsets.end())
1002 continue;
1003
1004 int RegOffset = Offset->second;
1005 if (RegOffset != CurOffset - 4) {
1006 DEBUG_WITH_TYPE("compact-unwind",
1007 llvm::dbgs() << MRI.getName(CSReg.Reg) << " saved at "
1008 << RegOffset << " but only supported at "
1009 << CurOffset << "\n");
1010 return CU::UNWIND_ARM_MODE_DWARF;
1011 }
1012 CompactUnwindEncoding |= CSReg.Encoding;
1013 CurOffset -= 4;
1014 }
1015
1016 // If no floats saved, we are done.
1017 if (FloatRegCount == 0)
1018 return CompactUnwindEncoding;
1019
1020 // Switch mode to include D register saving.
1021 CompactUnwindEncoding &= ~CU::UNWIND_ARM_MODE_MASK;
1022 CompactUnwindEncoding |= CU::UNWIND_ARM_MODE_FRAME_D;
1023
1024 // FIXME: supporting more than 4 saved D-registers compactly would be trivial,
1025 // but needs coordination with the linker and libunwind.
1026 if (FloatRegCount > 4) {
1027 DEBUG_WITH_TYPE("compact-unwind",
1028 llvm::dbgs() << "unsupported number of D registers saved ("
1029 << FloatRegCount << ")\n");
1030 return CU::UNWIND_ARM_MODE_DWARF;
1031 }
1032
1033 // Floating point registers must either be saved sequentially, or we defer to
1034 // DWARF. No gaps allowed here so check that each saved d-register is
1035 // precisely where it should be.
1036 static unsigned FPRCSRegs[] = { ARM::D8, ARM::D10, ARM::D12, ARM::D14 };
1037 for (int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
1038 auto Offset = RegOffsets.find(FPRCSRegs[Idx]);
1039 if (Offset == RegOffsets.end()) {
1040 DEBUG_WITH_TYPE("compact-unwind",
1041 llvm::dbgs() << FloatRegCount << " D-regs saved, but "
1042 << MRI.getName(FPRCSRegs[Idx])
1043 << " not saved\n");
1044 return CU::UNWIND_ARM_MODE_DWARF;
1045 } else if (Offset->second != CurOffset - 8) {
1046 DEBUG_WITH_TYPE("compact-unwind",
1047 llvm::dbgs() << FloatRegCount << " D-regs saved, but "
1048 << MRI.getName(FPRCSRegs[Idx])
1049 << " saved at " << Offset->second
1050 << ", expected at " << CurOffset - 8
1051 << "\n");
1052 return CU::UNWIND_ARM_MODE_DWARF;
1053 }
1054 CurOffset -= 8;
1055 }
1056
1057 return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
1058}
1059
Vedant Kumar366dd9fd2015-08-21 21:52:48 +00001060static MachO::CPUSubTypeARM getMachOSubTypeFromArch(StringRef Arch) {
Chandler Carruthbb47b9a2015-08-30 02:09:48 +00001061 unsigned AK = ARM::parseArch(Arch);
Vedant Kumar366dd9fd2015-08-21 21:52:48 +00001062 switch (AK) {
1063 default:
1064 return MachO::CPU_SUBTYPE_ARM_V7;
1065 case ARM::AK_ARMV4T:
1066 return MachO::CPU_SUBTYPE_ARM_V4T;
Artyom Skrobov2c2f3782015-11-12 15:51:41 +00001067 case ARM::AK_ARMV5T:
1068 case ARM::AK_ARMV5TE:
1069 case ARM::AK_ARMV5TEJ:
1070 return MachO::CPU_SUBTYPE_ARM_V5;
Vedant Kumar366dd9fd2015-08-21 21:52:48 +00001071 case ARM::AK_ARMV6:
1072 case ARM::AK_ARMV6K:
1073 return MachO::CPU_SUBTYPE_ARM_V6;
Artyom Skrobov2c2f3782015-11-12 15:51:41 +00001074 case ARM::AK_ARMV7A:
Vedant Kumar366dd9fd2015-08-21 21:52:48 +00001075 return MachO::CPU_SUBTYPE_ARM_V7;
1076 case ARM::AK_ARMV7S:
1077 return MachO::CPU_SUBTYPE_ARM_V7S;
1078 case ARM::AK_ARMV7K:
1079 return MachO::CPU_SUBTYPE_ARM_V7K;
1080 case ARM::AK_ARMV6M:
Vedant Kumar366dd9fd2015-08-21 21:52:48 +00001081 return MachO::CPU_SUBTYPE_ARM_V6M;
1082 case ARM::AK_ARMV7M:
1083 return MachO::CPU_SUBTYPE_ARM_V7M;
1084 case ARM::AK_ARMV7EM:
1085 return MachO::CPU_SUBTYPE_ARM_V7EM;
1086 }
1087}
1088
Bill Wendling58e2d3d2013-09-09 02:37:14 +00001089MCAsmBackend *llvm::createARMAsmBackend(const Target &T,
Daniel Sanders418caf52015-06-10 10:35:34 +00001090 const MCRegisterInfo &MRI,
Daniel Sanders50f17232015-09-15 16:17:27 +00001091 const Triple &TheTriple, StringRef CPU,
Daniel Sanders418caf52015-06-10 10:35:34 +00001092 bool isLittle) {
Daniel Sanders50f17232015-09-15 16:17:27 +00001093 switch (TheTriple.getObjectFormat()) {
Joe Abbey8e72eb72014-09-16 09:18:23 +00001094 default:
1095 llvm_unreachable("unsupported object format");
Daniel Sanders50f17232015-09-15 16:17:27 +00001096 case Triple::MachO: {
1097 MachO::CPUSubTypeARM CS = getMachOSubTypeFromArch(TheTriple.getArchName());
Tim Northoverf8e47e42015-10-28 22:56:36 +00001098 return new ARMAsmBackendDarwin(T, TheTriple, MRI, CS);
Owen Anderson975ddf82011-04-01 21:07:39 +00001099 }
Daniel Sanders50f17232015-09-15 16:17:27 +00001100 case Triple::COFF:
1101 assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported");
1102 return new ARMAsmBackendWinCOFF(T, TheTriple);
1103 case Triple::ELF:
1104 assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target");
1105 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
1106 return new ARMAsmBackendELF(T, TheTriple, OSABI, isLittle);
Saleem Abdulrasool84b952b2014-04-27 03:48:22 +00001107 }
Jason W Kimb3212452010-09-30 02:17:26 +00001108}
Christian Pirker2a111602014-03-28 14:35:30 +00001109
Christian Pirkerdc9ff752014-04-01 15:19:30 +00001110MCAsmBackend *llvm::createARMLEAsmBackend(const Target &T,
Christian Pirker2a111602014-03-28 14:35:30 +00001111 const MCRegisterInfo &MRI,
Daniel Sanders50f17232015-09-15 16:17:27 +00001112 const Triple &TT, StringRef CPU) {
Christian Pirker2a111602014-03-28 14:35:30 +00001113 return createARMAsmBackend(T, MRI, TT, CPU, true);
1114}
1115
Christian Pirkerdc9ff752014-04-01 15:19:30 +00001116MCAsmBackend *llvm::createARMBEAsmBackend(const Target &T,
Christian Pirker2a111602014-03-28 14:35:30 +00001117 const MCRegisterInfo &MRI,
Daniel Sanders50f17232015-09-15 16:17:27 +00001118 const Triple &TT, StringRef CPU) {
Christian Pirker2a111602014-03-28 14:35:30 +00001119 return createARMAsmBackend(T, MRI, TT, CPU, false);
1120}
1121
Christian Pirkerdc9ff752014-04-01 15:19:30 +00001122MCAsmBackend *llvm::createThumbLEAsmBackend(const Target &T,
Joe Abbey8e72eb72014-09-16 09:18:23 +00001123 const MCRegisterInfo &MRI,
Daniel Sanders50f17232015-09-15 16:17:27 +00001124 const Triple &TT, StringRef CPU) {
Christian Pirker2a111602014-03-28 14:35:30 +00001125 return createARMAsmBackend(T, MRI, TT, CPU, true);
1126}
1127
Christian Pirkerdc9ff752014-04-01 15:19:30 +00001128MCAsmBackend *llvm::createThumbBEAsmBackend(const Target &T,
Joe Abbey8e72eb72014-09-16 09:18:23 +00001129 const MCRegisterInfo &MRI,
Daniel Sanders50f17232015-09-15 16:17:27 +00001130 const Triple &TT, StringRef CPU) {
Christian Pirker2a111602014-03-28 14:35:30 +00001131 return createARMAsmBackend(T, MRI, TT, CPU, false);
1132}