X86AsmBackend.cpp revision df09270ae897e7fa64a7c162de163c32ee181a03
1//===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "llvm/MC/MCAsmBackend.h" 11#include "MCTargetDesc/X86BaseInfo.h" 12#include "MCTargetDesc/X86FixupKinds.h" 13#include "llvm/ADT/Twine.h" 14#include "llvm/MC/MCAssembler.h" 15#include "llvm/MC/MCELFObjectWriter.h" 16#include "llvm/MC/MCExpr.h" 17#include "llvm/MC/MCFixupKindInfo.h" 18#include "llvm/MC/MCMachObjectWriter.h" 19#include "llvm/MC/MCObjectWriter.h" 20#include "llvm/MC/MCSectionCOFF.h" 21#include "llvm/MC/MCSectionELF.h" 22#include "llvm/MC/MCSectionMachO.h" 23#include "llvm/Object/MachOFormat.h" 24#include "llvm/Support/CommandLine.h" 25#include "llvm/Support/ELF.h" 26#include "llvm/Support/ErrorHandling.h" 27#include "llvm/Support/TargetRegistry.h" 28#include "llvm/Support/raw_ostream.h" 29using namespace llvm; 30 31// Option to allow disabling arithmetic relaxation to workaround PR9807, which 32// is useful when running bitwise comparison experiments on Darwin. We should be 33// able to remove this once PR9807 is resolved. 34static cl::opt<bool> 35MCDisableArithRelaxation("mc-x86-disable-arith-relaxation", 36 cl::desc("Disable relaxation of arithmetic instruction for X86")); 37 38static unsigned getFixupKindLog2Size(unsigned Kind) { 39 switch (Kind) { 40 default: assert(0 && "invalid fixup kind!"); 41 case FK_PCRel_1: 42 case FK_Data_1: return 0; 43 case FK_PCRel_2: 44 case FK_Data_2: return 1; 45 case FK_PCRel_4: 46 case X86::reloc_riprel_4byte: 47 case X86::reloc_riprel_4byte_movq_load: 48 case X86::reloc_signed_4byte: 49 case X86::reloc_global_offset_table: 50 case X86::reloc_coff_secrel32: 51 case FK_Data_4: return 2; 52 case FK_PCRel_8: 53 case FK_Data_8: return 3; 54 } 55} 56 57namespace { 58 59class X86ELFObjectWriter : public MCELFObjectTargetWriter { 60public: 61 X86ELFObjectWriter(bool is64Bit, uint8_t OSABI, uint16_t EMachine, 62 bool HasRelocationAddend, bool foobar) 63 : MCELFObjectTargetWriter(is64Bit, OSABI, EMachine, HasRelocationAddend) {} 64}; 65 66class X86AsmBackend : public MCAsmBackend { 67public: 68 X86AsmBackend(const Target &T) 69 : MCAsmBackend() {} 70 71 unsigned getNumFixupKinds() const { 72 return X86::NumTargetFixupKinds; 73 } 74 75 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { 76 const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { 77 { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, 78 { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel}, 79 { "reloc_signed_4byte", 0, 4 * 8, 0}, 80 { "reloc_global_offset_table", 0, 4 * 8, 0}, 81 { "reloc_coff_secrel32", 0, 4 * 8, 0} 82 }; 83 84 if (Kind < FirstTargetFixupKind) 85 return MCAsmBackend::getFixupKindInfo(Kind); 86 87 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 88 "Invalid kind!"); 89 return Infos[Kind - FirstTargetFixupKind]; 90 } 91 92 void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 93 uint64_t Value) const { 94 unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); 95 96 assert(Fixup.getOffset() + Size <= DataSize && 97 "Invalid fixup offset!"); 98 99 // Check that uppper bits are either all zeros or all ones. 100 // Specifically ignore overflow/underflow as long as the leakage is 101 // limited to the lower bits. This is to remain compatible with 102 // other assemblers. 103 assert(isIntN(Size * 8 + 1, Value) && 104 "Value does not fit in the Fixup field"); 105 106 for (unsigned i = 0; i != Size; ++i) 107 Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); 108 } 109 110 bool MayNeedRelaxation(const MCInst &Inst) const; 111 112 bool fixupNeedsRelaxation(const MCFixup &Fixup, 113 uint64_t Value, 114 const MCInstFragment *DF, 115 const MCAsmLayout &Layout) const; 116 117 void RelaxInstruction(const MCInst &Inst, MCInst &Res) const; 118 119 bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const; 120}; 121} // end anonymous namespace 122 123static unsigned getRelaxedOpcodeBranch(unsigned Op) { 124 switch (Op) { 125 default: 126 return Op; 127 128 case X86::JAE_1: return X86::JAE_4; 129 case X86::JA_1: return X86::JA_4; 130 case X86::JBE_1: return X86::JBE_4; 131 case X86::JB_1: return X86::JB_4; 132 case X86::JE_1: return X86::JE_4; 133 case X86::JGE_1: return X86::JGE_4; 134 case X86::JG_1: return X86::JG_4; 135 case X86::JLE_1: return X86::JLE_4; 136 case X86::JL_1: return X86::JL_4; 137 case X86::JMP_1: return X86::JMP_4; 138 case X86::JNE_1: return X86::JNE_4; 139 case X86::JNO_1: return X86::JNO_4; 140 case X86::JNP_1: return X86::JNP_4; 141 case X86::JNS_1: return X86::JNS_4; 142 case X86::JO_1: return X86::JO_4; 143 case X86::JP_1: return X86::JP_4; 144 case X86::JS_1: return X86::JS_4; 145 } 146} 147 148static unsigned getRelaxedOpcodeArith(unsigned Op) { 149 switch (Op) { 150 default: 151 return Op; 152 153 // IMUL 154 case X86::IMUL16rri8: return X86::IMUL16rri; 155 case X86::IMUL16rmi8: return X86::IMUL16rmi; 156 case X86::IMUL32rri8: return X86::IMUL32rri; 157 case X86::IMUL32rmi8: return X86::IMUL32rmi; 158 case X86::IMUL64rri8: return X86::IMUL64rri32; 159 case X86::IMUL64rmi8: return X86::IMUL64rmi32; 160 161 // AND 162 case X86::AND16ri8: return X86::AND16ri; 163 case X86::AND16mi8: return X86::AND16mi; 164 case X86::AND32ri8: return X86::AND32ri; 165 case X86::AND32mi8: return X86::AND32mi; 166 case X86::AND64ri8: return X86::AND64ri32; 167 case X86::AND64mi8: return X86::AND64mi32; 168 169 // OR 170 case X86::OR16ri8: return X86::OR16ri; 171 case X86::OR16mi8: return X86::OR16mi; 172 case X86::OR32ri8: return X86::OR32ri; 173 case X86::OR32mi8: return X86::OR32mi; 174 case X86::OR64ri8: return X86::OR64ri32; 175 case X86::OR64mi8: return X86::OR64mi32; 176 177 // XOR 178 case X86::XOR16ri8: return X86::XOR16ri; 179 case X86::XOR16mi8: return X86::XOR16mi; 180 case X86::XOR32ri8: return X86::XOR32ri; 181 case X86::XOR32mi8: return X86::XOR32mi; 182 case X86::XOR64ri8: return X86::XOR64ri32; 183 case X86::XOR64mi8: return X86::XOR64mi32; 184 185 // ADD 186 case X86::ADD16ri8: return X86::ADD16ri; 187 case X86::ADD16mi8: return X86::ADD16mi; 188 case X86::ADD32ri8: return X86::ADD32ri; 189 case X86::ADD32mi8: return X86::ADD32mi; 190 case X86::ADD64ri8: return X86::ADD64ri32; 191 case X86::ADD64mi8: return X86::ADD64mi32; 192 193 // SUB 194 case X86::SUB16ri8: return X86::SUB16ri; 195 case X86::SUB16mi8: return X86::SUB16mi; 196 case X86::SUB32ri8: return X86::SUB32ri; 197 case X86::SUB32mi8: return X86::SUB32mi; 198 case X86::SUB64ri8: return X86::SUB64ri32; 199 case X86::SUB64mi8: return X86::SUB64mi32; 200 201 // CMP 202 case X86::CMP16ri8: return X86::CMP16ri; 203 case X86::CMP16mi8: return X86::CMP16mi; 204 case X86::CMP32ri8: return X86::CMP32ri; 205 case X86::CMP32mi8: return X86::CMP32mi; 206 case X86::CMP64ri8: return X86::CMP64ri32; 207 case X86::CMP64mi8: return X86::CMP64mi32; 208 209 // PUSH 210 case X86::PUSHi8: return X86::PUSHi32; 211 case X86::PUSHi16: return X86::PUSHi32; 212 case X86::PUSH64i8: return X86::PUSH64i32; 213 case X86::PUSH64i16: return X86::PUSH64i32; 214 } 215} 216 217static unsigned getRelaxedOpcode(unsigned Op) { 218 unsigned R = getRelaxedOpcodeArith(Op); 219 if (R != Op) 220 return R; 221 return getRelaxedOpcodeBranch(Op); 222} 223 224bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst) const { 225 // Branches can always be relaxed. 226 if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode()) 227 return true; 228 229 if (MCDisableArithRelaxation) 230 return false; 231 232 // Check if this instruction is ever relaxable. 233 if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode()) 234 return false; 235 236 237 // Check if it has an expression and is not RIP relative. 238 bool hasExp = false; 239 bool hasRIP = false; 240 for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { 241 const MCOperand &Op = Inst.getOperand(i); 242 if (Op.isExpr()) 243 hasExp = true; 244 245 if (Op.isReg() && Op.getReg() == X86::RIP) 246 hasRIP = true; 247 } 248 249 // FIXME: Why exactly do we need the !hasRIP? Is it just a limitation on 250 // how we do relaxations? 251 return hasExp && !hasRIP; 252} 253 254bool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, 255 uint64_t Value, 256 const MCInstFragment *DF, 257 const MCAsmLayout &Layout) const { 258 // Relax if the value is too big for a (signed) i8. 259 return int64_t(Value) != int64_t(int8_t(Value)); 260} 261 262// FIXME: Can tblgen help at all here to verify there aren't other instructions 263// we can relax? 264void X86AsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const { 265 // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel. 266 unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); 267 268 if (RelaxedOp == Inst.getOpcode()) { 269 SmallString<256> Tmp; 270 raw_svector_ostream OS(Tmp); 271 Inst.dump_pretty(OS); 272 OS << "\n"; 273 report_fatal_error("unexpected instruction to relax: " + OS.str()); 274 } 275 276 Res = Inst; 277 Res.setOpcode(RelaxedOp); 278} 279 280/// WriteNopData - Write optimal nops to the output file for the \arg Count 281/// bytes. This returns the number of bytes written. It may return 0 if 282/// the \arg Count is more than the maximum optimal nops. 283bool X86AsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const { 284 static const uint8_t Nops[10][10] = { 285 // nop 286 {0x90}, 287 // xchg %ax,%ax 288 {0x66, 0x90}, 289 // nopl (%[re]ax) 290 {0x0f, 0x1f, 0x00}, 291 // nopl 0(%[re]ax) 292 {0x0f, 0x1f, 0x40, 0x00}, 293 // nopl 0(%[re]ax,%[re]ax,1) 294 {0x0f, 0x1f, 0x44, 0x00, 0x00}, 295 // nopw 0(%[re]ax,%[re]ax,1) 296 {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 297 // nopl 0L(%[re]ax) 298 {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 299 // nopl 0L(%[re]ax,%[re]ax,1) 300 {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 301 // nopw 0L(%[re]ax,%[re]ax,1) 302 {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 303 // nopw %cs:0L(%[re]ax,%[re]ax,1) 304 {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 305 }; 306 307 // Write an optimal sequence for the first 15 bytes. 308 const uint64_t OptimalCount = (Count < 16) ? Count : 15; 309 const uint64_t Prefixes = OptimalCount <= 10 ? 0 : OptimalCount - 10; 310 for (uint64_t i = 0, e = Prefixes; i != e; i++) 311 OW->Write8(0x66); 312 const uint64_t Rest = OptimalCount - Prefixes; 313 for (uint64_t i = 0, e = Rest; i != e; i++) 314 OW->Write8(Nops[Rest - 1][i]); 315 316 // Finish with single byte nops. 317 for (uint64_t i = OptimalCount, e = Count; i != e; ++i) 318 OW->Write8(0x90); 319 320 return true; 321} 322 323/* *** */ 324 325namespace { 326class ELFX86AsmBackend : public X86AsmBackend { 327public: 328 uint8_t OSABI; 329 ELFX86AsmBackend(const Target &T, uint8_t _OSABI) 330 : X86AsmBackend(T), OSABI(_OSABI) { 331 HasReliableSymbolDifference = true; 332 } 333 334 virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 335 const MCSectionELF &ES = static_cast<const MCSectionELF&>(Section); 336 return ES.getFlags() & ELF::SHF_MERGE; 337 } 338}; 339 340class ELFX86_32AsmBackend : public ELFX86AsmBackend { 341public: 342 ELFX86_32AsmBackend(const Target &T, uint8_t OSABI) 343 : ELFX86AsmBackend(T, OSABI) {} 344 345 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 346 return createX86ELFObjectWriter(OS, /*Is64Bit*/ false, OSABI); 347 } 348}; 349 350class ELFX86_64AsmBackend : public ELFX86AsmBackend { 351public: 352 ELFX86_64AsmBackend(const Target &T, uint8_t OSABI) 353 : ELFX86AsmBackend(T, OSABI) {} 354 355 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 356 return createX86ELFObjectWriter(OS, /*Is64Bit*/ true, OSABI); 357 } 358}; 359 360class WindowsX86AsmBackend : public X86AsmBackend { 361 bool Is64Bit; 362 363public: 364 WindowsX86AsmBackend(const Target &T, bool is64Bit) 365 : X86AsmBackend(T) 366 , Is64Bit(is64Bit) { 367 } 368 369 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 370 return createX86WinCOFFObjectWriter(OS, Is64Bit); 371 } 372}; 373 374class DarwinX86AsmBackend : public X86AsmBackend { 375public: 376 DarwinX86AsmBackend(const Target &T) 377 : X86AsmBackend(T) { } 378}; 379 380class DarwinX86_32AsmBackend : public DarwinX86AsmBackend { 381public: 382 DarwinX86_32AsmBackend(const Target &T) 383 : DarwinX86AsmBackend(T) {} 384 385 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 386 return createX86MachObjectWriter(OS, /*Is64Bit=*/false, 387 object::mach::CTM_i386, 388 object::mach::CSX86_ALL); 389 } 390}; 391 392class DarwinX86_64AsmBackend : public DarwinX86AsmBackend { 393public: 394 DarwinX86_64AsmBackend(const Target &T) 395 : DarwinX86AsmBackend(T) { 396 HasReliableSymbolDifference = true; 397 } 398 399 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 400 return createX86MachObjectWriter(OS, /*Is64Bit=*/true, 401 object::mach::CTM_x86_64, 402 object::mach::CSX86_ALL); 403 } 404 405 virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 406 // Temporary labels in the string literals sections require symbols. The 407 // issue is that the x86_64 relocation format does not allow symbol + 408 // offset, and so the linker does not have enough information to resolve the 409 // access to the appropriate atom unless an external relocation is used. For 410 // non-cstring sections, we expect the compiler to use a non-temporary label 411 // for anything that could have an addend pointing outside the symbol. 412 // 413 // See <rdar://problem/4765733>. 414 const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 415 return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS; 416 } 417 418 virtual bool isSectionAtomizable(const MCSection &Section) const { 419 const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 420 // Fixed sized data sections are uniqued, they cannot be diced into atoms. 421 switch (SMO.getType()) { 422 default: 423 return true; 424 425 case MCSectionMachO::S_4BYTE_LITERALS: 426 case MCSectionMachO::S_8BYTE_LITERALS: 427 case MCSectionMachO::S_16BYTE_LITERALS: 428 case MCSectionMachO::S_LITERAL_POINTERS: 429 case MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS: 430 case MCSectionMachO::S_LAZY_SYMBOL_POINTERS: 431 case MCSectionMachO::S_MOD_INIT_FUNC_POINTERS: 432 case MCSectionMachO::S_MOD_TERM_FUNC_POINTERS: 433 case MCSectionMachO::S_INTERPOSING: 434 return false; 435 } 436 } 437}; 438 439} // end anonymous namespace 440 441MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, StringRef TT) { 442 Triple TheTriple(TT); 443 444 if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) 445 return new DarwinX86_32AsmBackend(T); 446 447 if (TheTriple.isOSWindows()) 448 return new WindowsX86AsmBackend(T, false); 449 450 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 451 return new ELFX86_32AsmBackend(T, OSABI); 452} 453 454MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringRef TT) { 455 Triple TheTriple(TT); 456 457 if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) 458 return new DarwinX86_64AsmBackend(T); 459 460 if (TheTriple.isOSWindows()) 461 return new WindowsX86AsmBackend(T, true); 462 463 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 464 return new ELFX86_64AsmBackend(T, OSABI); 465} 466