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 10a87e40f16f1c3117412e01107807e490d6fb29bcEvan Cheng#include "MCTargetDesc/X86BaseInfo.h" 118c3fee59038d8fd98db2a01b6a309a8941a16a3fEvan Cheng#include "MCTargetDesc/X86FixupKinds.h" 1235de9946d5fc01d2fed970bdcc7966bad92bdbc4Jim Grosbach#include "llvm/ADT/StringSwitch.h" 1379aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "llvm/MC/MCAsmBackend.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" 23f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar#include "llvm/Support/CommandLine.h" 24eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck#include "llvm/Support/ELF.h" 25829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar#include "llvm/Support/ErrorHandling.h" 265510728d28bb1ee04abc32da3d21b7df12948053Charles Davis#include "llvm/Support/MachO.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) { 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable("invalid fixup kind!"); 42e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 43ce618af3e880ae0ec0ddd81aca8ed5bbd4096ae4Rafael Espindola case FK_SecRel_1: 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_Data_1: 45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return 0; 46e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_2: 47ce618af3e880ae0ec0ddd81aca8ed5bbd4096ae4Rafael Espindola case FK_SecRel_2: 48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_Data_2: 49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return 1; 50e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 5187190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar case X86::reloc_riprel_4byte: 5287190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar case X86::reloc_riprel_4byte_movq_load: 53a8c02c3bdd68e65d14fb6b0d56989663754059b0Rafael Espindola case X86::reloc_signed_4byte: 5424ba4f7f5f27c8d64be7ad653863b33594e5f019Rafael Espindola case X86::reloc_global_offset_table: 55ce618af3e880ae0ec0ddd81aca8ed5bbd4096ae4Rafael Espindola case FK_SecRel_4: 56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_Data_4: 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return 2; 583a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_8: 59ce618af3e880ae0ec0ddd81aca8ed5bbd4096ae4Rafael Espindola case FK_SecRel_8: 60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case FK_Data_8: 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case X86::reloc_global_offset_table8: 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return 3; 6387190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar } 6487190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar} 6587190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar 669fc05227a2596c545b845ed9a72673995e49d16bChris Lattnernamespace { 67ae5abd595f5442767313a4c8a24008ad19323cebDaniel Dunbar 686024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolaclass X86ELFObjectWriter : public MCELFObjectTargetWriter { 696024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolapublic: 70dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola X86ELFObjectWriter(bool is64Bit, uint8_t OSABI, uint16_t EMachine, 71dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola bool HasRelocationAddend, bool foobar) 72dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola : MCELFObjectTargetWriter(is64Bit, OSABI, EMachine, HasRelocationAddend) {} 736024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola}; 746024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola 7578c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Chengclass X86AsmBackend : public MCAsmBackend { 76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const StringRef CPU; 775943d4e3eea9ad5ef55618c075262337463aafa9Bill Wendling bool HasNopl; 78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const uint64_t MaxNopLength; 7912783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbarpublic: 80536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky X86AsmBackend(const Target &T, StringRef _CPU) 81cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : MCAsmBackend(), CPU(_CPU), MaxNopLength(_CPU == "slm" ? 7 : 15) { 825943d4e3eea9ad5ef55618c075262337463aafa9Bill Wendling HasNopl = CPU != "generic" && CPU != "i386" && CPU != "i486" && 835943d4e3eea9ad5ef55618c075262337463aafa9Bill Wendling CPU != "i586" && CPU != "pentium" && CPU != "pentium-mmx" && 845943d4e3eea9ad5ef55618c075262337463aafa9Bill Wendling CPU != "i686" && CPU != "k6" && CPU != "k6-2" && CPU != "k6-3" && 855943d4e3eea9ad5ef55618c075262337463aafa9Bill Wendling CPU != "geode" && CPU != "winchip-c6" && CPU != "winchip2" && 865943d4e3eea9ad5ef55618c075262337463aafa9Bill Wendling CPU != "c3" && CPU != "c3-2"; 875943d4e3eea9ad5ef55618c075262337463aafa9Bill Wendling } 8887190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getNumFixupKinds() const override { 902761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar return X86::NumTargetFixupKinds; 912761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar } 922761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { 942761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { 952761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, 962761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel}, 972761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar { "reloc_signed_4byte", 0, 4 * 8, 0}, 98ce618af3e880ae0ec0ddd81aca8ed5bbd4096ae4Rafael Espindola { "reloc_global_offset_table", 0, 4 * 8, 0} 992761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar }; 1002761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 1012761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar if (Kind < FirstTargetFixupKind) 10278c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng return MCAsmBackend::getFixupKindInfo(Kind); 1032761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 1042761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 1052761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar "Invalid kind!"); 1062761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar return Infos[Kind - FirstTargetFixupKind]; 1072761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar } 1082761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 109ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Value, bool IsPCRel) const override { 111482ad802f1b1885542ea8a30e144a228a1526912Daniel Dunbar unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); 11287190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar 113179821ac1f282ef6f8d24d5ea346028aee8ba4c7Rafael Espindola assert(Fixup.getOffset() + Size <= DataSize && 11487190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar "Invalid fixup offset!"); 115e651983e71a0fbe624a1441dfc8b747ca1a038f1Jason W Kim 1164dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim // Check that uppper bits are either all zeros or all ones. 1174dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim // Specifically ignore overflow/underflow as long as the leakage is 1184dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim // limited to the lower bits. This is to remain compatible with 1194dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim // other assemblers. 120d83a54fd35026b540b54df43abae0618d4527668Eli Friedman assert(isIntN(Size * 8 + 1, Value) && 1214dd963b196e843989fc7a1f3b39b19bf858fc4f7Jason W Kim "Value does not fit in the Fixup field"); 122e651983e71a0fbe624a1441dfc8b747ca1a038f1Jason W Kim 12387190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar for (unsigned i = 0; i != Size; ++i) 124179821ac1f282ef6f8d24d5ea346028aee8ba4c7Rafael Espindola Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); 12587190c473c216e481e0a70475577e496b3a3449eDaniel Dunbar } 126829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool mayNeedRelaxation(const MCInst &Inst) const override; 128337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, 130251040bc18eedfa56d01fe92836e55cfd8c5d990Eli Bendersky const MCRelaxableFragment *DF, 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCAsmLayout &Layout) const override; 132370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void relaxInstruction(const MCInst &Inst, MCInst &Res) const override; 1348f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; 13612783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar}; 137ec38de2ca87d738aa3d4d5c36740f29f1a9f27deMichael J. Spencer} // end anonymous namespace 13812783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar 139e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindolastatic unsigned getRelaxedOpcodeBranch(unsigned Op) { 140829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar switch (Op) { 141829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar default: 142829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar return Op; 143829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar 144829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JAE_1: return X86::JAE_4; 145829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JA_1: return X86::JA_4; 146829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JBE_1: return X86::JBE_4; 147829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JB_1: return X86::JB_4; 148829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JE_1: return X86::JE_4; 149829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JGE_1: return X86::JGE_4; 150829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JG_1: return X86::JG_4; 151829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JLE_1: return X86::JLE_4; 152829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JL_1: return X86::JL_4; 153829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JMP_1: return X86::JMP_4; 154829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JNE_1: return X86::JNE_4; 155829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JNO_1: return X86::JNO_4; 156829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JNP_1: return X86::JNP_4; 157829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JNS_1: return X86::JNS_4; 158829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JO_1: return X86::JO_4; 159829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JP_1: return X86::JP_4; 160829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar case X86::JS_1: return X86::JS_4; 161829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar } 162829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar} 163829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar 164e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindolastatic unsigned getRelaxedOpcodeArith(unsigned Op) { 165e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola switch (Op) { 166e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola default: 167e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola return Op; 168e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 169e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // IMUL 170e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::IMUL16rri8: return X86::IMUL16rri; 171e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::IMUL16rmi8: return X86::IMUL16rmi; 172e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::IMUL32rri8: return X86::IMUL32rri; 173e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::IMUL32rmi8: return X86::IMUL32rmi; 174e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::IMUL64rri8: return X86::IMUL64rri32; 175e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::IMUL64rmi8: return X86::IMUL64rmi32; 176e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 177e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // AND 178e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::AND16ri8: return X86::AND16ri; 179e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::AND16mi8: return X86::AND16mi; 180e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::AND32ri8: return X86::AND32ri; 181e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::AND32mi8: return X86::AND32mi; 182e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::AND64ri8: return X86::AND64ri32; 183e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::AND64mi8: return X86::AND64mi32; 184e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 185e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // OR 186e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::OR16ri8: return X86::OR16ri; 187e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::OR16mi8: return X86::OR16mi; 188e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::OR32ri8: return X86::OR32ri; 189e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::OR32mi8: return X86::OR32mi; 190e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::OR64ri8: return X86::OR64ri32; 191e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::OR64mi8: return X86::OR64mi32; 192e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 193e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // XOR 194e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::XOR16ri8: return X86::XOR16ri; 195e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::XOR16mi8: return X86::XOR16mi; 196e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::XOR32ri8: return X86::XOR32ri; 197e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::XOR32mi8: return X86::XOR32mi; 198e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::XOR64ri8: return X86::XOR64ri32; 199e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::XOR64mi8: return X86::XOR64mi32; 200e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 201e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // ADD 202e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::ADD16ri8: return X86::ADD16ri; 203e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::ADD16mi8: return X86::ADD16mi; 204e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::ADD32ri8: return X86::ADD32ri; 205e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::ADD32mi8: return X86::ADD32mi; 206e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::ADD64ri8: return X86::ADD64ri32; 207e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::ADD64mi8: return X86::ADD64mi32; 208e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 209e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // SUB 210e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::SUB16ri8: return X86::SUB16ri; 211e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::SUB16mi8: return X86::SUB16mi; 212e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::SUB32ri8: return X86::SUB32ri; 213e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::SUB32mi8: return X86::SUB32mi; 214e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::SUB64ri8: return X86::SUB64ri32; 215e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::SUB64mi8: return X86::SUB64mi32; 216e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 217e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // CMP 218e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::CMP16ri8: return X86::CMP16ri; 219e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::CMP16mi8: return X86::CMP16mi; 220e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::CMP32ri8: return X86::CMP32ri; 221e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::CMP32mi8: return X86::CMP32mi; 222e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::CMP64ri8: return X86::CMP64ri32; 223e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola case X86::CMP64mi8: return X86::CMP64mi32; 2241ee03a835ebb79bee998191f89d2785228771fb1Rafael Espindola 2251ee03a835ebb79bee998191f89d2785228771fb1Rafael Espindola // PUSH 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::PUSH32i8: return X86::PUSHi32; 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::PUSH16i8: return X86::PUSHi16; 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::PUSH64i8: return X86::PUSH64i32; 2295232cc675c59ac04df616c45158f15c3c166f5d8Eli Friedman case X86::PUSH64i16: return X86::PUSH64i32; 230e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola } 231e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola} 232e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 233e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindolastatic unsigned getRelaxedOpcode(unsigned Op) { 234e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola unsigned R = getRelaxedOpcodeArith(Op); 235e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola if (R != Op) 236e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola return R; 237e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola return getRelaxedOpcodeBranch(Op); 238e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola} 239e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 240ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbachbool X86AsmBackend::mayNeedRelaxation(const MCInst &Inst) const { 241e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // Branches can always be relaxed. 242e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode()) 243e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola return true; 244e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 245f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar if (MCDisableArithRelaxation) 246f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar return false; 247f86500bc4f9b0e7078df9a17b84e95fbf37080a7Daniel Dunbar 24884882528551bd816464a0657ad581c1fed0ac865Daniel Dunbar // Check if this instruction is ever relaxable. 249e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode()) 25084882528551bd816464a0657ad581c1fed0ac865Daniel Dunbar return false; 251482ad802f1b1885542ea8a30e144a228a1526912Daniel Dunbar 252e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 253e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // Check if it has an expression and is not RIP relative. 254e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola bool hasExp = false; 255e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola bool hasRIP = false; 256e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { 257e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola const MCOperand &Op = Inst.getOperand(i); 258e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola if (Op.isExpr()) 259e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola hasExp = true; 260e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 261e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola if (Op.isReg() && Op.getReg() == X86::RIP) 262e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola hasRIP = true; 263e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola } 264e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola 265e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // FIXME: Why exactly do we need the !hasRIP? Is it just a limitation on 266e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola // how we do relaxations? 267e4f506ff4ba8ddc70b6b7c77feceabb0b53b6ccfRafael Espindola return hasExp && !hasRIP; 268337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar} 269337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar 270370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbachbool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, 271370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach uint64_t Value, 272251040bc18eedfa56d01fe92836e55cfd8c5d990Eli Bendersky const MCRelaxableFragment *DF, 273370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach const MCAsmLayout &Layout) const { 274370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach // Relax if the value is too big for a (signed) i8. 275370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach return int64_t(Value) != int64_t(int8_t(Value)); 276370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach} 277370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach 278829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar// FIXME: Can tblgen help at all here to verify there aren't other instructions 279829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar// we can relax? 280ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbachvoid X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { 281829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel. 28295506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); 283829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar 28495506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar if (RelaxedOp == Inst.getOpcode()) { 285829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar SmallString<256> Tmp; 286829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar raw_svector_ostream OS(Tmp); 28795506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar Inst.dump_pretty(OS); 288c9adb8c61e5dacdb340509ff6090cada1f4b591cDaniel Dunbar OS << "\n"; 28975361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("unexpected instruction to relax: " + OS.str()); 290829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar } 291829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar 29295506d40c5bafc72aeebd96dca2b0f92bd0480f1Daniel Dunbar Res = Inst; 293829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar Res.setOpcode(RelaxedOp); 294829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar} 295829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar 296e1d31008c9950ada1a92d0499acb001a2dd76a84Eli Bendersky/// \brief Write a sequence of optimal nops to the output, covering \p Count 297e1d31008c9950ada1a92d0499acb001a2dd76a84Eli Bendersky/// bytes. 298e1d31008c9950ada1a92d0499acb001a2dd76a84Eli Bendersky/// \return - true on success, false on failure 299ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbachbool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { 3002ace1b68ac717fc284b64944a38705ff57871ba2Rafael Espindola static const uint8_t Nops[10][10] = { 3018f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nop 3028f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x90}, 3038f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // xchg %ax,%ax 3048f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x66, 0x90}, 3058f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nopl (%[re]ax) 3068f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x0f, 0x1f, 0x00}, 3078f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nopl 0(%[re]ax) 3088f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x0f, 0x1f, 0x40, 0x00}, 3098f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nopl 0(%[re]ax,%[re]ax,1) 3108f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x0f, 0x1f, 0x44, 0x00, 0x00}, 3118f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nopw 0(%[re]ax,%[re]ax,1) 3128f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 3138f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nopl 0L(%[re]ax) 3148f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 3158f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nopl 0L(%[re]ax,%[re]ax,1) 3168f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 3178f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nopw 0L(%[re]ax,%[re]ax,1) 3188f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 3198f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar // nopw %cs:0L(%[re]ax,%[re]ax,1) 3208f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 3218f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar }; 3228f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // This CPU doesn't support long nops. If needed add more. 324126afcbf654e42dc3f659a1a66bfa8a784e7bd46Benjamin Kramer // FIXME: Can we get this from the subtarget somehow? 3259ed81d16f71b60c246a7b8e9ed4fdd58a48ce4b9Bill Wendling // FIXME: We could generated something better than plain 0x90. 3265943d4e3eea9ad5ef55618c075262337463aafa9Bill Wendling if (!HasNopl) { 327536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky for (uint64_t i = 0; i < Count; ++i) 328536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky OW->Write8(0x90); 329536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky return true; 330536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky } 331536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky 3326c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr // 15 is the longest single nop instruction. Emit as many 15-byte nops as 3336c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr // needed, then emit a nop of the remaining length. 3346c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr do { 335cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength); 3366c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10; 3376c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr for (uint8_t i = 0; i < Prefixes; i++) 3386c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr OW->Write8(0x66); 3396c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr const uint8_t Rest = ThisNopLength - Prefixes; 3406c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr for (uint8_t i = 0; i < Rest; i++) 3416c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr OW->Write8(Nops[Rest - 1][i]); 3426c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr Count -= ThisNopLength; 3436c4265a541c9e431961113c1a5d92fb4628bfe13David Sehr } while (Count != 0); 3448f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar 3458f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar return true; 3468f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar} 3478f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar 348829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar/* *** */ 349829680048cdfea7498587a03f815915f1c0e1965Daniel Dunbar 3509fc05227a2596c545b845ed9a72673995e49d16bChris Lattnernamespace { 3513373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 352cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbarclass ELFX86AsmBackend : public X86AsmBackend { 353cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbarpublic: 354dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola uint8_t OSABI; 355536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky ELFX86AsmBackend(const Target &T, uint8_t _OSABI, StringRef CPU) 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : X86AsmBackend(T, CPU), OSABI(_OSABI) {} 357cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbar}; 358cc5b84c6fba79a798e86ea604e54ca9429273a13Daniel Dunbar 3597efaef6b822089349b44f15392e0da73a05ebb0aMatt Flemingclass ELFX86_32AsmBackend : public ELFX86AsmBackend { 3607efaef6b822089349b44f15392e0da73a05ebb0aMatt Flemingpublic: 361536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky ELFX86_32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) 362536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky : ELFX86AsmBackend(T, OSABI, CPU) {} 363453db50333723cb59c64970b6860caa0a7c0b8c2Matt Fleming 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { 365678c35c3861df3d5882553da45e79a89dae20294Michael Liao return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, ELF::EM_386); 366d1cba8727a1ee713030d9e6bbd72523a9f9e2a60Jan Sjödin } 3677efaef6b822089349b44f15392e0da73a05ebb0aMatt Fleming}; 3687efaef6b822089349b44f15392e0da73a05ebb0aMatt Fleming 369cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass ELFX86_X32AsmBackend : public ELFX86AsmBackend { 370cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinespublic: 371cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ELFX86_X32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) 372cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : ELFX86AsmBackend(T, OSABI, CPU) {} 373cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 374cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { 375cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, 376cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ELF::EM_X86_64); 377cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 378cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}; 379cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 3807efaef6b822089349b44f15392e0da73a05ebb0aMatt Flemingclass ELFX86_64AsmBackend : public ELFX86AsmBackend { 3817efaef6b822089349b44f15392e0da73a05ebb0aMatt Flemingpublic: 382536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) 383536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky : ELFX86AsmBackend(T, OSABI, CPU) {} 384453db50333723cb59c64970b6860caa0a7c0b8c2Matt Fleming 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { 386678c35c3861df3d5882553da45e79a89dae20294Michael Liao return createX86ELFObjectWriter(OS, /*IsELF64*/ true, OSABI, ELF::EM_X86_64); 387d1cba8727a1ee713030d9e6bbd72523a9f9e2a60Jan Sjödin } 3887efaef6b822089349b44f15392e0da73a05ebb0aMatt Fleming}; 3897efaef6b822089349b44f15392e0da73a05ebb0aMatt Fleming 390dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencerclass WindowsX86AsmBackend : public X86AsmBackend { 391da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer bool Is64Bit; 392f230df9af4012f9510de664b6d62b128e26a5861Rafael Espindola 393dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencerpublic: 394536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky WindowsX86AsmBackend(const Target &T, bool is64Bit, StringRef CPU) 395536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky : X86AsmBackend(T, CPU) 396da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer , Is64Bit(is64Bit) { 397dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer } 398dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { 400df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola return createX86WinCOFFObjectWriter(OS, Is64Bit); 401dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer } 402dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer}; 403dfd30187c685c2c5200ee795c64885c0a39dc2d0Michael J. Spencer 4043373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendlingnamespace CU { 4053373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 4063373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling /// Compact unwind encoding values. 4073373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling enum CompactUnwindEncodings { 4083373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling /// [RE]BP based frame where [RE]BP is pused on the stack immediately after 4093373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling /// the return address, then [RE]SP is moved to [RE]BP. 4103373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling UNWIND_MODE_BP_FRAME = 0x01000000, 4113373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 4123373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling /// A frameless function with a small constant stack size. 4133373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling UNWIND_MODE_STACK_IMMD = 0x02000000, 4143373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 4153373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling /// A frameless function with a large constant stack size. 4163373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling UNWIND_MODE_STACK_IND = 0x03000000, 4173373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 4183373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling /// No compact unwind encoding is available. 4193373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling UNWIND_MODE_DWARF = 0x04000000, 4203373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 4213373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling /// Mask for encoding the frame registers. 4223373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling UNWIND_BP_FRAME_REGISTERS = 0x00007FFF, 4233373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 4243373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling /// Mask for encoding the frameless registers. 4253373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF 4263373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling }; 4273373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 4283373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling} // end CU namespace 4293373f3bb3f4d37a79a33351d1aa2b879b1fdb794Bill Wendling 43023ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbarclass DarwinX86AsmBackend : public X86AsmBackend { 431c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling const MCRegisterInfo &MRI; 432c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 433c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// \brief Number of registers that can be saved in a compact unwind encoding. 434c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling enum { CU_NUM_SAVED_REGS = 6 }; 435c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 436c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling mutable unsigned SavedRegs[CU_NUM_SAVED_REGS]; 437c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling bool Is64Bit; 438c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 439c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned OffsetSize; ///< Offset of a "push" instruction. 440c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned PushInstrSize; ///< Size of a "push" instruction. 441c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned MoveInstrSize; ///< Size of a "move" instruction. 442c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned StackDivide; ///< Amount to adjust stack stize by. 443c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendlingprotected: 444c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// \brief Implementation of algorithm to generate the compact unwind encoding 445c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// for the CFI instructions. 446c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t 447c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling generateCompactUnwindEncodingImpl(ArrayRef<MCCFIInstruction> Instrs) const { 448c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (Instrs.empty()) return 0; 449c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 450c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Reset the saved registers. 451c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned SavedRegIdx = 0; 452c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling memset(SavedRegs, 0, sizeof(SavedRegs)); 453c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 454c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling bool HasFP = false; 455c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 456c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Encode that we are using EBP/RBP as the frame pointer. 457c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t CompactUnwindEncoding = 0; 458c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 459c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned SubtractInstrIdx = Is64Bit ? 3 : 2; 460c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned InstrOffset = 0; 461c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned StackAdjust = 0; 462c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned StackSize = 0; 463c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned PrevStackSize = 0; 464c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned NumDefCFAOffsets = 0; 465c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 466c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { 467c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling const MCCFIInstruction &Inst = Instrs[i]; 468c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 469c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling switch (Inst.getOperation()) { 470c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling default: 471dc7eb3e023e34adc9d40e93626467cfe22756f4cJim Grosbach // Any other CFI directives indicate a frame that we aren't prepared 472dc7eb3e023e34adc9d40e93626467cfe22756f4cJim Grosbach // to represent via compact unwind, so just bail out. 473dc7eb3e023e34adc9d40e93626467cfe22756f4cJim Grosbach return 0; 474c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case MCCFIInstruction::OpDefCfaRegister: { 475c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Defines a frame pointer. E.g. 476c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 477c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // movq %rsp, %rbp 478c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // L0: 479c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // .cfi_def_cfa_register %rbp 480c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 481c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling HasFP = true; 482c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling assert(MRI.getLLVMRegNum(Inst.getRegister(), true) == 483c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling (Is64Bit ? X86::RBP : X86::EBP) && "Invalid frame pointer!"); 484c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 485c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Reset the counts. 486c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling memset(SavedRegs, 0, sizeof(SavedRegs)); 487c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StackAdjust = 0; 488c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling SavedRegIdx = 0; 489c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling InstrOffset += MoveInstrSize; 490c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 491c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 492c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case MCCFIInstruction::OpDefCfaOffset: { 493c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Defines a new offset for the CFA. E.g. 494c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 495c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // With frame: 496c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 497c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // pushq %rbp 498c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // L0: 499c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // .cfi_def_cfa_offset 16 500c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 501c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Without frame: 502c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 503c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // subq $72, %rsp 504c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // L0: 505c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // .cfi_def_cfa_offset 80 506c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 507c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling PrevStackSize = StackSize; 508c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StackSize = std::abs(Inst.getOffset()) / StackDivide; 509c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling ++NumDefCFAOffsets; 510c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 511c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 512c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case MCCFIInstruction::OpOffset: { 513c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Defines a "push" of a callee-saved register. E.g. 514c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 515c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // pushq %r15 516c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // pushq %r14 517c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // pushq %rbx 518c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // L0: 519c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // subq $120, %rsp 520c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // L1: 521c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // .cfi_offset %rbx, -40 522c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // .cfi_offset %r14, -32 523c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // .cfi_offset %r15, -24 524c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 525c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (SavedRegIdx == CU_NUM_SAVED_REGS) 526c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // If there are too many saved registers, we cannot use a compact 527c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // unwind encoding. 528c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return CU::UNWIND_MODE_DWARF; 529c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 530c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned Reg = MRI.getLLVMRegNum(Inst.getRegister(), true); 531c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling SavedRegs[SavedRegIdx++] = Reg; 532c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StackAdjust += OffsetSize; 533c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling InstrOffset += PushInstrSize; 534c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 535c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 536c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 537c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 538c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 539c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StackAdjust /= StackDivide; 540c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 541c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (HasFP) { 542c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if ((StackAdjust & 0xFF) != StackAdjust) 543c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Offset was too big for a compact unwind encoding. 544c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return CU::UNWIND_MODE_DWARF; 545c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 546c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Get the encoding of the saved registers when we have a frame pointer. 547c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(); 548c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; 549c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 550c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME; 551c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16; 552c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS; 553c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } else { 554c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // If the amount of the stack allocation is the size of a register, then 555c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // we "push" the RAX/EAX register onto the stack instead of adjusting the 556c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // stack pointer with a SUB instruction. We don't support the push of the 557c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // RAX/EAX register with compact unwind. So we check for that situation 558c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // here. 559c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if ((NumDefCFAOffsets == SavedRegIdx + 1 && 560c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StackSize - PrevStackSize == 1) || 561c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling (Instrs.size() == 1 && NumDefCFAOffsets == 1 && StackSize == 2)) 562c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return CU::UNWIND_MODE_DWARF; 563c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 564c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling SubtractInstrIdx += InstrOffset; 565c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling ++StackAdjust; 566c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 567c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if ((StackSize & 0xFF) == StackSize) { 568c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Frameless stack with a small stack size. 569c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD; 570c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 571c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Encode the stack size. 572c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= (StackSize & 0xFF) << 16; 573c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } else { 574c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if ((StackAdjust & 0x7) != StackAdjust) 575c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // The extra stack adjustments are too big for us to handle. 576c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return CU::UNWIND_MODE_DWARF; 577c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 578c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Frameless stack with an offset too large for us to encode compactly. 579c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND; 580c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 581c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP' 582c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // instruction. 583c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16; 584c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 585c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Encode any extra stack stack adjustments (done via push 586c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // instructions). 587c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= (StackAdjust & 0x7) << 13; 588c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 589c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 590c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Encode the number of registers saved. (Reverse the list first.) 591c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]); 592c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10; 593c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 594c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Get the encoding of the saved registers when we don't have a frame 595c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // pointer. 596c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx); 597c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; 598c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 599c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Encode the register encoding. 600c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling CompactUnwindEncoding |= 601c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION; 602c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 603c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 604c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return CompactUnwindEncoding; 605c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 606c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 607c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendlingprivate: 608c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// \brief Get the compact unwind number for a given register. The number 609c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// corresponds to the enum lists in compact_unwind_encoding.h. 610c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling int getCompactUnwindRegNum(unsigned Reg) const { 611c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling static const uint16_t CU32BitRegs[7] = { 612c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 613c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling }; 614c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling static const uint16_t CU64BitRegs[] = { 615c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 616c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling }; 617c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling const uint16_t *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs; 618c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling for (int Idx = 1; *CURegs; ++CURegs, ++Idx) 619c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (*CURegs == Reg) 620c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return Idx; 621c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 622c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return -1; 623c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 624c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 625c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// \brief Return the registers encoded for a compact encoding with a frame 626c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// pointer. 627c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t encodeCompactUnwindRegistersWithFrame() const { 628c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Encode the registers in the order they were saved --- 3-bits per 629c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // register. The list of saved registers is assumed to be in reverse 630c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS. 631c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t RegEnc = 0; 632c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) { 633c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned Reg = SavedRegs[i]; 634c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (Reg == 0) break; 635c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 636c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling int CURegNum = getCompactUnwindRegNum(Reg); 637c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (CURegNum == -1) return ~0U; 638c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 639c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Encode the 3-bit register number in order, skipping over 3-bits for 640c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // each register. 641c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling RegEnc |= (CURegNum & 0x7) << (Idx++ * 3); 642c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 643c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 644c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling assert((RegEnc & 0x3FFFF) == RegEnc && 645c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling "Invalid compact register encoding!"); 646c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return RegEnc; 647c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 648c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 649c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// \brief Create the permutation encoding used with frameless stacks. It is 650c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// passed the number of registers to be saved and an array of the registers 651c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// saved. 652c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const { 653c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // The saved registers are numbered from 1 to 6. In order to encode the 654c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // order in which they were saved, we re-number them according to their 655c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // place in the register order. The re-numbering is relative to the last 656c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in 657c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // that order: 658c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 659c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Orig Re-Num 660c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // ---- ------ 661c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 6 6 662c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 2 2 663c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 4 3 664c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 5 3 665c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // 666c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) { 667c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling int CUReg = getCompactUnwindRegNum(SavedRegs[i]); 668c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (CUReg == -1) return ~0U; 669c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling SavedRegs[i] = CUReg; 670c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 671c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 672c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Reverse the list. 673c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]); 674c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 675c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t RenumRegs[CU_NUM_SAVED_REGS]; 676c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){ 677c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling unsigned Countless = 0; 678c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j) 679c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling if (SavedRegs[j] < SavedRegs[i]) 680c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling ++Countless; 681c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 682c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling RenumRegs[i] = SavedRegs[i] - Countless - 1; 683c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 684c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 685c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling // Take the renumbered values and encode them into a 10-bit number. 686c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling uint32_t permutationEncoding = 0; 687c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling switch (RegCount) { 688c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case 6: 689c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] 690c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling + 6 * RenumRegs[2] + 2 * RenumRegs[3] 691c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling + RenumRegs[4]; 692c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 693c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case 5: 694c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2] 695c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling + 6 * RenumRegs[3] + 2 * RenumRegs[4] 696c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling + RenumRegs[5]; 697c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 698c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case 4: 699c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3] 700c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling + 3 * RenumRegs[4] + RenumRegs[5]; 701c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 702c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case 3: 703c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4] 704c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling + RenumRegs[5]; 705c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 706c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case 2: 707c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5]; 708c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 709c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling case 1: 710c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling permutationEncoding |= RenumRegs[5]; 711c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling break; 712c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 713c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 714c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling assert((permutationEncoding & 0x3FF) == permutationEncoding && 715c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling "Invalid compact register encoding!"); 716c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling return permutationEncoding; 717c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 718c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 71923ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbarpublic: 720c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef CPU, 721c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling bool Is64Bit) 722c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling : X86AsmBackend(T, CPU), MRI(MRI), Is64Bit(Is64Bit) { 723c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling memset(SavedRegs, 0, sizeof(SavedRegs)); 724c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling OffsetSize = Is64Bit ? 8 : 4; 725c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling MoveInstrSize = Is64Bit ? 3 : 2; 726c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StackDivide = Is64Bit ? 8 : 4; 727c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling PushInstrSize = 1; 728c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 72923ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbar}; 73023ac7c78e4f009e0baa6d42f4fd0143769fbed4aDaniel Dunbar 731d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbarclass DarwinX86_32AsmBackend : public DarwinX86AsmBackend { 732d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbarpublic: 733c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling DarwinX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI, 734cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef CPU) 735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : DarwinX86AsmBackend(T, MRI, CPU, false) {} 7361a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar 73736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { 7389b2f25e3132524166d7669d52fffd6c6b6eaaf44Daniel Dunbar return createX86MachObjectWriter(OS, /*Is64Bit=*/false, 7395510728d28bb1ee04abc32da3d21b7df12948053Charles Davis MachO::CPU_TYPE_I386, 7405510728d28bb1ee04abc32da3d21b7df12948053Charles Davis MachO::CPU_SUBTYPE_I386_ALL); 7411a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar } 742c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 743c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// \brief Generate the compact unwind encoding for the CFI instructions. 74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t generateCompactUnwindEncoding( 74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ArrayRef<MCCFIInstruction> Instrs) const override { 746cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return generateCompactUnwindEncodingImpl(Instrs); 747c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 748d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar}; 749d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar 750d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbarclass DarwinX86_64AsmBackend : public DarwinX86AsmBackend { 75135de9946d5fc01d2fed970bdcc7966bad92bdbc4Jim Grosbach const MachO::CPUSubTypeX86 Subtype; 752d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbarpublic: 753c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling DarwinX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, 754cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef CPU, MachO::CPUSubTypeX86 st) 755cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : DarwinX86AsmBackend(T, MRI, CPU, true), Subtype(st) {} 756d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar 75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { 7589b2f25e3132524166d7669d52fffd6c6b6eaaf44Daniel Dunbar return createX86MachObjectWriter(OS, /*Is64Bit=*/true, 75935de9946d5fc01d2fed970bdcc7966bad92bdbc4Jim Grosbach MachO::CPU_TYPE_X86_64, Subtype); 7601a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar } 7611a9158c301b58d8119664f416461d5a5549170c4Daniel Dunbar 76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doesSectionRequireSymbols(const MCSection &Section) const override { 763d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar // Temporary labels in the string literals sections require symbols. The 764d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar // issue is that the x86_64 relocation format does not allow symbol + 765d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar // offset, and so the linker does not have enough information to resolve the 766d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar // access to the appropriate atom unless an external relocation is used. For 767d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar // non-cstring sections, we expect the compiler to use a non-temporary label 768d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar // for anything that could have an addend pointing outside the symbol. 769d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar // 770d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar // See <rdar://problem/4765733>. 771d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SMO.getType() == MachO::S_CSTRING_LITERALS; 773d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar } 774a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isSectionAtomizable(const MCSection &Section) const override { 776a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 777a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar // Fixed sized data sections are uniqued, they cannot be diced into atoms. 778a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar switch (SMO.getType()) { 779a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar default: 780a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar return true; 781a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar 78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_4BYTE_LITERALS: 78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_8BYTE_LITERALS: 78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_16BYTE_LITERALS: 78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_LITERAL_POINTERS: 78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_NON_LAZY_SYMBOL_POINTERS: 78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_LAZY_SYMBOL_POINTERS: 78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_MOD_INIT_FUNC_POINTERS: 78936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_MOD_TERM_FUNC_POINTERS: 79036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::S_INTERPOSING: 791a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar return false; 792a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar } 793a5f1d57f65ae601ec181c0f4e36cf0df5e8d79d8Daniel Dunbar } 794c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling 795c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling /// \brief Generate the compact unwind encoding for the CFI instructions. 79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t generateCompactUnwindEncoding( 79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ArrayRef<MCCFIInstruction> Instrs) const override { 798cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return generateCompactUnwindEncodingImpl(Instrs); 799c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling } 800d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar}; 801d6e59084d07500f68548652b8197325809a0c0c2Daniel Dunbar 802ec38de2ca87d738aa3d4d5c36740f29f1a9f27deMichael J. Spencer} // end anonymous namespace 80312783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar 804c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill WendlingMCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, 805c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling const MCRegisterInfo &MRI, 806c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StringRef TT, 807c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StringRef CPU) { 808912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar Triple TheTriple(TT); 809912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 81036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TheTriple.isOSBinFormatMachO()) 811cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return new DarwinX86_32AsmBackend(T, MRI, CPU); 812912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) 814536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky return new WindowsX86AsmBackend(T, false, CPU); 815912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 816dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 817536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky return new ELFX86_32AsmBackend(T, OSABI, CPU); 81812783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar} 81912783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar 820c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill WendlingMCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, 821c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling const MCRegisterInfo &MRI, 822c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StringRef TT, 823c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling StringRef CPU) { 824912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar Triple TheTriple(TT); 825912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 82636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TheTriple.isOSBinFormatMachO()) { 82735de9946d5fc01d2fed970bdcc7966bad92bdbc4Jim Grosbach MachO::CPUSubTypeX86 CS = 82835de9946d5fc01d2fed970bdcc7966bad92bdbc4Jim Grosbach StringSwitch<MachO::CPUSubTypeX86>(TheTriple.getArchName()) 82935de9946d5fc01d2fed970bdcc7966bad92bdbc4Jim Grosbach .Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H) 83035de9946d5fc01d2fed970bdcc7966bad92bdbc4Jim Grosbach .Default(MachO::CPU_SUBTYPE_X86_64_ALL); 831cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return new DarwinX86_64AsmBackend(T, MRI, CPU, CS); 83235de9946d5fc01d2fed970bdcc7966bad92bdbc4Jim Grosbach } 833912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) 835536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky return new WindowsX86AsmBackend(T, true, CPU); 836912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 837dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 838cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 839cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (TheTriple.getEnvironment() == Triple::GNUX32) 840cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return new ELFX86_X32AsmBackend(T, OSABI, CPU); 841536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky return new ELFX86_64AsmBackend(T, OSABI, CPU); 84212783d1c3a86d1b5287b0703db6893ae1f283877Daniel Dunbar} 843