X86AsmBackend.cpp revision df09270ae897e7fa64a7c162de163c32ee181a03
112783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar//===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===//
212783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar//
312783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar//                     The LLVM Compiler Infrastructure
412783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar//
512783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar// This file is distributed under the University of Illinois Open Source
612783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar// License. See LICENSE.TXT for details.
712783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar//
812783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar//===----------------------------------------------------------------------===//
912783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar
1078c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h"
11a87e40f16f1c3117412e01107807e490d6fb29bcEvan Cheng#include "MCTargetDesc/X86BaseInfo.h"
128c3fee59038d8fd98db2a01b6a309a8941a16a3fEvan Cheng#include "MCTargetDesc/X86FixupKinds.h"
13829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar#include "llvm/ADT/Twine.h"
1487190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar#include "llvm/MC/MCAssembler.h"
15285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola#include "llvm/MC/MCELFObjectWriter.h"
16a5d0b54ec156dd31a77a7994e9552a562cd2bf8cDaniel Dunbar#include "llvm/MC/MCExpr.h"
172761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar#include "llvm/MC/MCFixupKindInfo.h"
18aa4b7dd13ba83152473950d7014a29686dc7eef6Daniel Dunbar#include "llvm/MC/MCMachObjectWriter.h"
19337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar#include "llvm/MC/MCObjectWriter.h"
20dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer#include "llvm/MC/MCSectionCOFF.h"
21cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbar#include "llvm/MC/MCSectionELF.h"
22d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar#include "llvm/MC/MCSectionMachO.h"
2336d76a8dbc87b62de82a4a8c0d7cb4bb2a202934Daniel Dunbar#include "llvm/Object/MachOFormat.h"
24f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar#include "llvm/Support/CommandLine.h"
25eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck#include "llvm/Support/ELF.h"
26829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar#include "llvm/Support/ErrorHandling.h"
273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
28829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2912783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbarusing namespace llvm;
3012783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar
31f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar// Option to allow disabling arithmetic relaxation to workaround PR9807, which
32f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar// is useful when running bitwise comparison experiments on Darwin. We should be
33f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar// able to remove this once PR9807 is resolved.
34f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbarstatic cl::opt<bool>
35f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel DunbarMCDisableArithRelaxation("mc-x86-disable-arith-relaxation",
36f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar         cl::desc("Disable relaxation of arithmetic instruction for X86"));
37f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar
3887190c473c216e481e0a70475577e496b3a3449eDaniel Dunbarstatic unsigned getFixupKindLog2Size(unsigned Kind) {
3987190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  switch (Kind) {
4087190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  default: assert(0 && "invalid fixup kind!");
41e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola  case FK_PCRel_1:
4287190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  case FK_Data_1: return 0;
43e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola  case FK_PCRel_2:
4487190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  case FK_Data_2: return 1;
45e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola  case FK_PCRel_4:
4687190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  case X86::reloc_riprel_4byte:
4787190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  case X86::reloc_riprel_4byte_movq_load:
48a8c02c3bdd68e65d14fb6b0d56989663754059b0Rafael Espindola  case X86::reloc_signed_4byte:
4924ba4f7f5f27c8d64be7ad653863b33594e5f019Rafael Espindola  case X86::reloc_global_offset_table:
508f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola  case X86::reloc_coff_secrel32:
5187190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  case FK_Data_4: return 2;
523a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola  case FK_PCRel_8:
5387190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  case FK_Data_8: return 3;
5487190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  }
5587190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar}
5687190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar
579fc05227a2596c545b845ed9a72673995e49d16bChris Lattnernamespace {
58ae5abd595f5442767313a4c8a24008ad19323cebDaniel Dunbar
596024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolaclass X86ELFObjectWriter : public MCELFObjectTargetWriter {
606024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolapublic:
61dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  X86ELFObjectWriter(bool is64Bit, uint8_t OSABI, uint16_t EMachine,
62dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola                     bool HasRelocationAddend, bool foobar)
63dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola    : MCELFObjectTargetWriter(is64Bit, OSABI, EMachine, HasRelocationAddend) {}
646024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola};
656024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola
6678c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Chengclass X86AsmBackend : public MCAsmBackend {
6712783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbarpublic:
686c27f5e5743481c6a519c60135cf85ac238c150aDaniel Dunbar  X86AsmBackend(const Target &T)
6978c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng    : MCAsmBackend() {}
7087190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar
712761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar  unsigned getNumFixupKinds() const {
722761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar    return X86::NumTargetFixupKinds;
732761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar  }
742761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar
752761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
762761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar    const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = {
772761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar      { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel },
782761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar      { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel},
792761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar      { "reloc_signed_4byte", 0, 4 * 8, 0},
808f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola      { "reloc_global_offset_table", 0, 4 * 8, 0},
818f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola      { "reloc_coff_secrel32", 0, 4 * 8, 0}
822761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar    };
832761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar
842761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar    if (Kind < FirstTargetFixupKind)
8578c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng      return MCAsmBackend::getFixupKindInfo(Kind);
862761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar
872761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
882761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar           "Invalid kind!");
892761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar    return Infos[Kind - FirstTargetFixupKind];
902761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar  }
912761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar
92179821ac1f282ef6f8d24d5ea346028aee8ba4c7Rafael Espindola  void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
9387190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar                  uint64_t Value) const {
94482ad802f1b1885542ea8a30e144a228a1526912Daniel Dunbar    unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind());
9587190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar
96179821ac1f282ef6f8d24d5ea346028aee8ba4c7Rafael Espindola    assert(Fixup.getOffset() + Size <= DataSize &&
9787190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar           "Invalid fixup offset!");
98e651983e71a0fbe624a1441dfc8b747ca1a038f1Jason W Kim
994dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim    // Check that uppper bits are either all zeros or all ones.
1004dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim    // Specifically ignore overflow/underflow as long as the leakage is
1014dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim    // limited to the lower bits. This is to remain compatible with
1024dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim    // other assemblers.
103d83a54fd35026b540b54df43abae0618d4527668Eli Friedman    assert(isIntN(Size * 8 + 1, Value) &&
1044dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim           "Value does not fit in the Fixup field");
105e651983e71a0fbe624a1441dfc8b747ca1a038f1Jason W Kim
10687190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar    for (unsigned i = 0; i != Size; ++i)
107179821ac1f282ef6f8d24d5ea346028aee8ba4c7Rafael Espindola      Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8));
10887190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar  }
109829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar
11084882528551bd816464a0657ad581c1fed0ac865Daniel Dunbar  bool MayNeedRelaxation(const MCInst &Inst) const;
111337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar
112370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach  bool fixupNeedsRelaxation(const MCFixup &Fixup,
113370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach                            uint64_t Value,
114370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach                            const MCInstFragment *DF,
115370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach                            const MCAsmLayout &Layout) const;
116370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach
11795506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar  void RelaxInstruction(const MCInst &Inst, MCInst &Res) const;
1188f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar
1198f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar  bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;
12012783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar};
121ec38de2ca87d738aa3d4d5c36740f29f1a9f27deMichael J. Spencer} // end anonymous namespace
12212783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar
123e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindolastatic unsigned getRelaxedOpcodeBranch(unsigned Op) {
124829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  switch (Op) {
125829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  default:
126829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar    return Op;
127829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar
128829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JAE_1: return X86::JAE_4;
129829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JA_1:  return X86::JA_4;
130829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JBE_1: return X86::JBE_4;
131829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JB_1:  return X86::JB_4;
132829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JE_1:  return X86::JE_4;
133829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JGE_1: return X86::JGE_4;
134829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JG_1:  return X86::JG_4;
135829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JLE_1: return X86::JLE_4;
136829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JL_1:  return X86::JL_4;
137829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JMP_1: return X86::JMP_4;
138829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JNE_1: return X86::JNE_4;
139829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JNO_1: return X86::JNO_4;
140829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JNP_1: return X86::JNP_4;
141829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JNS_1: return X86::JNS_4;
142829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JO_1:  return X86::JO_4;
143829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JP_1:  return X86::JP_4;
144829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  case X86::JS_1:  return X86::JS_4;
145829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  }
146829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar}
147829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar
148e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindolastatic unsigned getRelaxedOpcodeArith(unsigned Op) {
149e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  switch (Op) {
150e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  default:
151e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    return Op;
152e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
153e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    // IMUL
154e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::IMUL16rri8: return X86::IMUL16rri;
155e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::IMUL16rmi8: return X86::IMUL16rmi;
156e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::IMUL32rri8: return X86::IMUL32rri;
157e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::IMUL32rmi8: return X86::IMUL32rmi;
158e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::IMUL64rri8: return X86::IMUL64rri32;
159e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::IMUL64rmi8: return X86::IMUL64rmi32;
160e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
161e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    // AND
162e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::AND16ri8: return X86::AND16ri;
163e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::AND16mi8: return X86::AND16mi;
164e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::AND32ri8: return X86::AND32ri;
165e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::AND32mi8: return X86::AND32mi;
166e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::AND64ri8: return X86::AND64ri32;
167e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::AND64mi8: return X86::AND64mi32;
168e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
169e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    // OR
170e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::OR16ri8: return X86::OR16ri;
171e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::OR16mi8: return X86::OR16mi;
172e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::OR32ri8: return X86::OR32ri;
173e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::OR32mi8: return X86::OR32mi;
174e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::OR64ri8: return X86::OR64ri32;
175e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::OR64mi8: return X86::OR64mi32;
176e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
177e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    // XOR
178e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::XOR16ri8: return X86::XOR16ri;
179e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::XOR16mi8: return X86::XOR16mi;
180e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::XOR32ri8: return X86::XOR32ri;
181e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::XOR32mi8: return X86::XOR32mi;
182e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::XOR64ri8: return X86::XOR64ri32;
183e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::XOR64mi8: return X86::XOR64mi32;
184e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
185e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    // ADD
186e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::ADD16ri8: return X86::ADD16ri;
187e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::ADD16mi8: return X86::ADD16mi;
188e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::ADD32ri8: return X86::ADD32ri;
189e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::ADD32mi8: return X86::ADD32mi;
190e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::ADD64ri8: return X86::ADD64ri32;
191e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::ADD64mi8: return X86::ADD64mi32;
192e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
193e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    // SUB
194e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::SUB16ri8: return X86::SUB16ri;
195e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::SUB16mi8: return X86::SUB16mi;
196e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::SUB32ri8: return X86::SUB32ri;
197e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::SUB32mi8: return X86::SUB32mi;
198e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::SUB64ri8: return X86::SUB64ri32;
199e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::SUB64mi8: return X86::SUB64mi32;
200e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
201e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    // CMP
202e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::CMP16ri8: return X86::CMP16ri;
203e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::CMP16mi8: return X86::CMP16mi;
204e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::CMP32ri8: return X86::CMP32ri;
205e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::CMP32mi8: return X86::CMP32mi;
206e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::CMP64ri8: return X86::CMP64ri32;
207e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  case X86::CMP64mi8: return X86::CMP64mi32;
2081ee03a835ebb79bee998191f89d2785228771fb1Rafael Espindola
2091ee03a835ebb79bee998191f89d2785228771fb1Rafael Espindola    // PUSH
2101ee03a835ebb79bee998191f89d2785228771fb1Rafael Espindola  case X86::PUSHi8: return X86::PUSHi32;
2115232cc675c59ac04df616c45158f15c3c166f5d8Eli Friedman  case X86::PUSHi16: return X86::PUSHi32;
2125232cc675c59ac04df616c45158f15c3c166f5d8Eli Friedman  case X86::PUSH64i8: return X86::PUSH64i32;
2135232cc675c59ac04df616c45158f15c3c166f5d8Eli Friedman  case X86::PUSH64i16: return X86::PUSH64i32;
214e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  }
215e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola}
216e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
217e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindolastatic unsigned getRelaxedOpcode(unsigned Op) {
218e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  unsigned R = getRelaxedOpcodeArith(Op);
219e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  if (R != Op)
220e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    return R;
221e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  return getRelaxedOpcodeBranch(Op);
222e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola}
223e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
22484882528551bd816464a0657ad581c1fed0ac865Daniel Dunbarbool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst) const {
225e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  // Branches can always be relaxed.
226e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode())
227e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    return true;
228e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
229f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar  if (MCDisableArithRelaxation)
230f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar    return false;
231f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar
23284882528551bd816464a0657ad581c1fed0ac865Daniel Dunbar  // Check if this instruction is ever relaxable.
233e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode())
23484882528551bd816464a0657ad581c1fed0ac865Daniel Dunbar    return false;
235482ad802f1b1885542ea8a30e144a228a1526912Daniel Dunbar
236e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
237e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  // Check if it has an expression and is not RIP relative.
238e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  bool hasExp = false;
239e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  bool hasRIP = false;
240e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  for (unsigned i = 0; i < Inst.getNumOperands(); ++i) {
241e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    const MCOperand &Op = Inst.getOperand(i);
242e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    if (Op.isExpr())
243e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola      hasExp = true;
244e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
245e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola    if (Op.isReg() && Op.getReg() == X86::RIP)
246e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola      hasRIP = true;
247e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  }
248e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola
249e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  // FIXME: Why exactly do we need the !hasRIP? Is it just a limitation on
250e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  // how we do relaxations?
251e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola  return hasExp && !hasRIP;
252337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar}
253337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar
254370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbachbool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
255370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach                                         uint64_t Value,
256370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach                                         const MCInstFragment *DF,
257370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach                                         const MCAsmLayout &Layout) const {
258370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach  // Relax if the value is too big for a (signed) i8.
259370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach  return int64_t(Value) != int64_t(int8_t(Value));
260370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach}
261370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach
262829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar// FIXME: Can tblgen help at all here to verify there aren't other instructions
263829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar// we can relax?
26495506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbarvoid X86AsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
265829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel.
26695506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar  unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode());
267829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar
26895506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar  if (RelaxedOp == Inst.getOpcode()) {
269829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar    SmallString<256> Tmp;
270829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar    raw_svector_ostream OS(Tmp);
27195506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar    Inst.dump_pretty(OS);
272c9adb8c61e5dacdb340509ff6090cada1f4b591cDaniel Dunbar    OS << "\n";
27375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("unexpected instruction to relax: " + OS.str());
274829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  }
275829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar
27695506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar  Res = Inst;
277829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar  Res.setOpcode(RelaxedOp);
278829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar}
279829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar
2808f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar/// WriteNopData - Write optimal nops to the output file for the \arg Count
2818f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar/// bytes.  This returns the number of bytes written.  It may return 0 if
2828f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar/// the \arg Count is more than the maximum optimal nops.
2838f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbarbool X86AsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
2842ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola  static const uint8_t Nops[10][10] = {
2858f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nop
2868f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x90},
2878f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // xchg %ax,%ax
2888f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x66, 0x90},
2898f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nopl (%[re]ax)
2908f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x0f, 0x1f, 0x00},
2918f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nopl 0(%[re]ax)
2928f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x0f, 0x1f, 0x40, 0x00},
2938f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nopl 0(%[re]ax,%[re]ax,1)
2948f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x0f, 0x1f, 0x44, 0x00, 0x00},
2958f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nopw 0(%[re]ax,%[re]ax,1)
2968f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
2978f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nopl 0L(%[re]ax)
2988f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
2998f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nopl 0L(%[re]ax,%[re]ax,1)
3008f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
3018f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nopw 0L(%[re]ax,%[re]ax,1)
3028f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
3038f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    // nopw %cs:0L(%[re]ax,%[re]ax,1)
3048f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar    {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
3058f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar  };
3068f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar
3078f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar  // Write an optimal sequence for the first 15 bytes.
3082ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola  const uint64_t OptimalCount = (Count < 16) ? Count : 15;
3092ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola  const uint64_t Prefixes = OptimalCount <= 10 ? 0 : OptimalCount - 10;
3102ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola  for (uint64_t i = 0, e = Prefixes; i != e; i++)
3112ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola    OW->Write8(0x66);
3122ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola  const uint64_t Rest = OptimalCount - Prefixes;
3132ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola  for (uint64_t i = 0, e = Rest; i != e; i++)
3142ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola    OW->Write8(Nops[Rest - 1][i]);
3158f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar
3168f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar  // Finish with single byte nops.
3178f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar  for (uint64_t i = OptimalCount, e = Count; i != e; ++i)
3188f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar   OW->Write8(0x90);
3198f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar
3208f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar  return true;
3218f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar}
3228f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar
323829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar/* *** */
324829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar
3259fc05227a2596c545b845ed9a72673995e49d16bChris Lattnernamespace {
326cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbarclass ELFX86AsmBackend : public X86AsmBackend {
327cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbarpublic:
328dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  uint8_t OSABI;
329dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  ELFX86AsmBackend(const Target &T, uint8_t _OSABI)
330dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola    : X86AsmBackend(T), OSABI(_OSABI) {
33173ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola    HasReliableSymbolDifference = true;
33273ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola  }
33373ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
33473ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
33573ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola    const MCSectionELF &ES = static_cast<const MCSectionELF&>(Section);
3361c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    return ES.getFlags() & ELF::SHF_MERGE;
337cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbar  }
338cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbar};
339cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbar
3407efaef6b822089349b44f15392e0da73a05ebb0aMatt Flemingclass ELFX86_32AsmBackend : public ELFX86AsmBackend {
3417efaef6b822089349b44f15392e0da73a05ebb0aMatt Flemingpublic:
342dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  ELFX86_32AsmBackend(const Target &T, uint8_t OSABI)
343dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola    : ELFX86AsmBackend(T, OSABI) {}
344453db50333723cb59c64970b6860caa0a7c0b8c2Matt Fleming
345453db50333723cb59c64970b6860caa0a7c0b8c2Matt Fleming  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
346edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    return createX86ELFObjectWriter(OS, /*Is64Bit*/ false, OSABI);
347d1cba8727a1ee713030d9e6bbd72523a9f9e2a60Jan Sjödin  }
3487efaef6b822089349b44f15392e0da73a05ebb0aMatt Fleming};
3497efaef6b822089349b44f15392e0da73a05ebb0aMatt Fleming
3507efaef6b822089349b44f15392e0da73a05ebb0aMatt Flemingclass ELFX86_64AsmBackend : public ELFX86AsmBackend {
3517efaef6b822089349b44f15392e0da73a05ebb0aMatt Flemingpublic:
352dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  ELFX86_64AsmBackend(const Target &T, uint8_t OSABI)
353dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola    : ELFX86AsmBackend(T, OSABI) {}
354453db50333723cb59c64970b6860caa0a7c0b8c2Matt Fleming
355453db50333723cb59c64970b6860caa0a7c0b8c2Matt Fleming  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
356edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    return createX86ELFObjectWriter(OS, /*Is64Bit*/ true, OSABI);
357d1cba8727a1ee713030d9e6bbd72523a9f9e2a60Jan Sjödin  }
3587efaef6b822089349b44f15392e0da73a05ebb0aMatt Fleming};
3597efaef6b822089349b44f15392e0da73a05ebb0aMatt Fleming
360dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencerclass WindowsX86AsmBackend : public X86AsmBackend {
361da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer  bool Is64Bit;
362f230df9af4012f9510de664b6d62b128e26a5861Rafael Espindola
363dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencerpublic:
364da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer  WindowsX86AsmBackend(const Target &T, bool is64Bit)
365da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer    : X86AsmBackend(T)
366da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer    , Is64Bit(is64Bit) {
367dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer  }
368dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer
369dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
370df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola    return createX86WinCOFFObjectWriter(OS, Is64Bit);
371dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer  }
372dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer};
373dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer
37423ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbarclass DarwinX86AsmBackend : public X86AsmBackend {
37523ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbarpublic:
37623ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbar  DarwinX86AsmBackend(const Target &T)
3777b62afac0a6f967e7466e60ceb26bfdcff2e59f4Daniel Dunbar    : X86AsmBackend(T) { }
37823ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbar};
37923ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbar
380d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbarclass DarwinX86_32AsmBackend : public DarwinX86AsmBackend {
381d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbarpublic:
382d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar  DarwinX86_32AsmBackend(const Target &T)
383d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    : DarwinX86AsmBackend(T) {}
3841a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar
3851a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
3869b2f25e3132524166d7669d52fffd6c6b6eaaf44Daniel Dunbar    return createX86MachObjectWriter(OS, /*Is64Bit=*/false,
3879b2f25e3132524166d7669d52fffd6c6b6eaaf44Daniel Dunbar                                     object::mach::CTM_i386,
3889b2f25e3132524166d7669d52fffd6c6b6eaaf44Daniel Dunbar                                     object::mach::CSX86_ALL);
3891a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar  }
390d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar};
391d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar
392d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbarclass DarwinX86_64AsmBackend : public DarwinX86AsmBackend {
393d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbarpublic:
394d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar  DarwinX86_64AsmBackend(const Target &T)
3950682951b4f569b9a162ddfcffaa90a3ba5adb231Daniel Dunbar    : DarwinX86AsmBackend(T) {
3960682951b4f569b9a162ddfcffaa90a3ba5adb231Daniel Dunbar    HasReliableSymbolDifference = true;
3970682951b4f569b9a162ddfcffaa90a3ba5adb231Daniel Dunbar  }
398d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar
3991a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
4009b2f25e3132524166d7669d52fffd6c6b6eaaf44Daniel Dunbar    return createX86MachObjectWriter(OS, /*Is64Bit=*/true,
4019b2f25e3132524166d7669d52fffd6c6b6eaaf44Daniel Dunbar                                     object::mach::CTM_x86_64,
4029b2f25e3132524166d7669d52fffd6c6b6eaaf44Daniel Dunbar                                     object::mach::CSX86_ALL);
4031a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar  }
4041a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar
405d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
406d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    // Temporary labels in the string literals sections require symbols. The
407d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    // issue is that the x86_64 relocation format does not allow symbol +
408d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    // offset, and so the linker does not have enough information to resolve the
409d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    // access to the appropriate atom unless an external relocation is used. For
410d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    // non-cstring sections, we expect the compiler to use a non-temporary label
411d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    // for anything that could have an addend pointing outside the symbol.
412d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    //
413d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    // See <rdar://problem/4765733>.
414d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
415d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS;
416d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar  }
417a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar
418a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar  virtual bool isSectionAtomizable(const MCSection &Section) const {
419a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
420a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    // Fixed sized data sections are uniqued, they cannot be diced into atoms.
421a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    switch (SMO.getType()) {
422a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    default:
423a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar      return true;
424a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar
425a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_4BYTE_LITERALS:
426a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_8BYTE_LITERALS:
427a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_16BYTE_LITERALS:
428a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_LITERAL_POINTERS:
429a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS:
430a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_LAZY_SYMBOL_POINTERS:
431a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_MOD_INIT_FUNC_POINTERS:
432a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_MOD_TERM_FUNC_POINTERS:
433a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    case MCSectionMachO::S_INTERPOSING:
434a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar      return false;
435a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar    }
436a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar  }
437d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar};
438d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar
439ec38de2ca87d738aa3d4d5c36740f29f1a9f27deMichael J. Spencer} // end anonymous namespace
44012783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar
44178c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan ChengMCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, StringRef TT) {
442912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar  Triple TheTriple(TT);
443912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar
444912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar  if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
445d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    return new DarwinX86_32AsmBackend(T);
446912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar
447912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar  if (TheTriple.isOSWindows())
448912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar    return new WindowsX86AsmBackend(T, false);
449912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar
450dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
451dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  return new ELFX86_32AsmBackend(T, OSABI);
45212783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar}
45312783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar
45478c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan ChengMCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringRef TT) {
455912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar  Triple TheTriple(TT);
456912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar
457912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar  if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
458d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar    return new DarwinX86_64AsmBackend(T);
459912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar
460912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar  if (TheTriple.isOSWindows())
461912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar    return new WindowsX86AsmBackend(T, true);
462912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar
463dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
464dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  return new ELFX86_64AsmBackend(T, OSABI);
46512783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar}
466