OLD | NEW |
1 //===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===// | 1 //===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #include "MCTargetDesc/X86BaseInfo.h" | 10 #include "MCTargetDesc/X86BaseInfo.h" |
11 #include "MCTargetDesc/X86FixupKinds.h" | 11 #include "MCTargetDesc/X86FixupKinds.h" |
| 12 #include "MCTargetDesc/X86MCNaCl.h" // @LOCALMOD |
12 #include "llvm/ADT/StringSwitch.h" | 13 #include "llvm/ADT/StringSwitch.h" |
13 #include "llvm/MC/MCAsmBackend.h" | 14 #include "llvm/MC/MCAsmBackend.h" |
14 #include "llvm/MC/MCELFObjectWriter.h" | 15 #include "llvm/MC/MCELFObjectWriter.h" |
15 #include "llvm/MC/MCExpr.h" | 16 #include "llvm/MC/MCExpr.h" |
16 #include "llvm/MC/MCFixupKindInfo.h" | 17 #include "llvm/MC/MCFixupKindInfo.h" |
17 #include "llvm/MC/MCMachObjectWriter.h" | 18 #include "llvm/MC/MCMachObjectWriter.h" |
18 #include "llvm/MC/MCObjectWriter.h" | 19 #include "llvm/MC/MCObjectWriter.h" |
19 #include "llvm/MC/MCSectionCOFF.h" | 20 #include "llvm/MC/MCSectionCOFF.h" |
20 #include "llvm/MC/MCSectionELF.h" | 21 #include "llvm/MC/MCSectionELF.h" |
21 #include "llvm/MC/MCSectionMachO.h" | 22 #include "llvm/MC/MCSectionMachO.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 return Infos[Kind - FirstTargetFixupKind]; | 106 return Infos[Kind - FirstTargetFixupKind]; |
106 } | 107 } |
107 | 108 |
108 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, | 109 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, |
109 uint64_t Value, bool IsPCRel) const override { | 110 uint64_t Value, bool IsPCRel) const override { |
110 unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); | 111 unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); |
111 | 112 |
112 assert(Fixup.getOffset() + Size <= DataSize && | 113 assert(Fixup.getOffset() + Size <= DataSize && |
113 "Invalid fixup offset!"); | 114 "Invalid fixup offset!"); |
114 | 115 |
| 116 // @LOCALMOD-BEGIN |
| 117 // This check breaks negative addends on x86-32. It makes x86-32 |
| 118 // behaviour inconsistent with x86-64 and ARM. |
| 119 // See: https://code.google.com/p/nativeclient/issues/detail?id=3548 |
| 120 #if 0 |
115 // Check that uppper bits are either all zeros or all ones. | 121 // Check that uppper bits are either all zeros or all ones. |
116 // Specifically ignore overflow/underflow as long as the leakage is | 122 // Specifically ignore overflow/underflow as long as the leakage is |
117 // limited to the lower bits. This is to remain compatible with | 123 // limited to the lower bits. This is to remain compatible with |
118 // other assemblers. | 124 // other assemblers. |
119 assert(isIntN(Size * 8 + 1, Value) && | 125 assert(isIntN(Size * 8 + 1, Value) && |
120 "Value does not fit in the Fixup field"); | 126 "Value does not fit in the Fixup field"); |
| 127 #endif |
| 128 // @LOCALMOD-END |
121 | 129 |
122 for (unsigned i = 0; i != Size; ++i) | 130 for (unsigned i = 0; i != Size; ++i) |
123 Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); | 131 Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); |
124 } | 132 } |
125 | 133 |
126 bool mayNeedRelaxation(const MCInst &Inst) const override; | 134 bool mayNeedRelaxation(const MCInst &Inst) const override; |
127 | 135 |
128 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, | 136 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, |
129 const MCRelaxableFragment *DF, | 137 const MCRelaxableFragment *DF, |
130 const MCAsmLayout &Layout) const override; | 138 const MCAsmLayout &Layout) const override; |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 class ELFX86_64AsmBackend : public ELFX86AsmBackend { | 387 class ELFX86_64AsmBackend : public ELFX86AsmBackend { |
380 public: | 388 public: |
381 ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) | 389 ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) |
382 : ELFX86AsmBackend(T, OSABI, CPU) {} | 390 : ELFX86AsmBackend(T, OSABI, CPU) {} |
383 | 391 |
384 MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { | 392 MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { |
385 return createX86ELFObjectWriter(OS, /*IsELF64*/ true, OSABI, ELF::EM_X86_64)
; | 393 return createX86ELFObjectWriter(OS, /*IsELF64*/ true, OSABI, ELF::EM_X86_64)
; |
386 } | 394 } |
387 }; | 395 }; |
388 | 396 |
| 397 // @LOCALMOD-BEGIN |
| 398 class NaClX86_32AsmBackend : public ELFX86_32AsmBackend { |
| 399 public: |
| 400 NaClX86_32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) |
| 401 : ELFX86_32AsmBackend(T, OSABI, CPU), |
| 402 STI(X86_MC::createX86MCSubtargetInfo("i386-unknown-nacl", CPU, "")) { |
| 403 State.PrefixSaved = 0; |
| 404 State.PrefixPass = false; |
| 405 State.EmitRaw = false; |
| 406 } |
| 407 ~NaClX86_32AsmBackend() override {} |
| 408 |
| 409 bool CustomExpandInst(const MCInst &Inst, MCStreamer &Out) override { |
| 410 return CustomExpandInstNaClX86(*STI, Inst, Out, State); |
| 411 } |
| 412 |
| 413 private: |
| 414 std::unique_ptr<MCSubtargetInfo> STI; |
| 415 X86MCNaClSFIState State; |
| 416 }; |
| 417 |
| 418 class NaClX86_64AsmBackend : public ELFX86_64AsmBackend { |
| 419 public: |
| 420 NaClX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) |
| 421 : ELFX86_64AsmBackend(T, OSABI, CPU), |
| 422 STI(X86_MC::createX86MCSubtargetInfo("x86_64-unknown-nacl", CPU, "")) { |
| 423 State.PrefixSaved = 0; |
| 424 State.PrefixPass = false; |
| 425 State.EmitRaw = false; |
| 426 } |
| 427 ~NaClX86_64AsmBackend() override {} |
| 428 |
| 429 bool CustomExpandInst(const MCInst &Inst, MCStreamer &Out) override { |
| 430 return CustomExpandInstNaClX86(*STI, Inst, Out, State); |
| 431 } |
| 432 |
| 433 private: |
| 434 std::unique_ptr<MCSubtargetInfo> STI; |
| 435 X86MCNaClSFIState State; |
| 436 }; |
| 437 // @LOCALMOD-END |
| 438 |
389 class WindowsX86AsmBackend : public X86AsmBackend { | 439 class WindowsX86AsmBackend : public X86AsmBackend { |
390 bool Is64Bit; | 440 bool Is64Bit; |
391 | 441 |
392 public: | 442 public: |
393 WindowsX86AsmBackend(const Target &T, bool is64Bit, StringRef CPU) | 443 WindowsX86AsmBackend(const Target &T, bool is64Bit, StringRef CPU) |
394 : X86AsmBackend(T, CPU) | 444 : X86AsmBackend(T, CPU) |
395 , Is64Bit(is64Bit) { | 445 , Is64Bit(is64Bit) { |
396 } | 446 } |
397 | 447 |
398 MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { | 448 MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 StringRef CPU) { | 875 StringRef CPU) { |
826 Triple TheTriple(TT); | 876 Triple TheTriple(TT); |
827 | 877 |
828 if (TheTriple.isOSBinFormatMachO()) | 878 if (TheTriple.isOSBinFormatMachO()) |
829 return new DarwinX86_32AsmBackend(T, MRI, CPU); | 879 return new DarwinX86_32AsmBackend(T, MRI, CPU); |
830 | 880 |
831 if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) | 881 if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) |
832 return new WindowsX86AsmBackend(T, false, CPU); | 882 return new WindowsX86AsmBackend(T, false, CPU); |
833 | 883 |
834 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); | 884 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); |
| 885 // @LOCALMOD-BEGIN |
| 886 if (TheTriple.isOSNaCl()) |
| 887 return new NaClX86_32AsmBackend(T, OSABI, CPU); |
| 888 // @LOCALMOD-END |
835 return new ELFX86_32AsmBackend(T, OSABI, CPU); | 889 return new ELFX86_32AsmBackend(T, OSABI, CPU); |
836 } | 890 } |
837 | 891 |
838 MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, | 892 MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, |
839 const MCRegisterInfo &MRI, | 893 const MCRegisterInfo &MRI, |
840 StringRef TT, | 894 StringRef TT, |
841 StringRef CPU) { | 895 StringRef CPU) { |
842 Triple TheTriple(TT); | 896 Triple TheTriple(TT); |
843 | 897 |
844 if (TheTriple.isOSBinFormatMachO()) { | 898 if (TheTriple.isOSBinFormatMachO()) { |
845 MachO::CPUSubTypeX86 CS = | 899 MachO::CPUSubTypeX86 CS = |
846 StringSwitch<MachO::CPUSubTypeX86>(TheTriple.getArchName()) | 900 StringSwitch<MachO::CPUSubTypeX86>(TheTriple.getArchName()) |
847 .Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H) | 901 .Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H) |
848 .Default(MachO::CPU_SUBTYPE_X86_64_ALL); | 902 .Default(MachO::CPU_SUBTYPE_X86_64_ALL); |
849 return new DarwinX86_64AsmBackend(T, MRI, CPU, CS); | 903 return new DarwinX86_64AsmBackend(T, MRI, CPU, CS); |
850 } | 904 } |
851 | 905 |
852 if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) | 906 if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) |
853 return new WindowsX86AsmBackend(T, true, CPU); | 907 return new WindowsX86AsmBackend(T, true, CPU); |
854 | 908 |
855 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); | 909 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); |
856 | 910 |
| 911 // @LOCALMOD-BEGIN |
| 912 if (TheTriple.isOSNaCl()) |
| 913 return new NaClX86_64AsmBackend(T, OSABI, CPU); |
| 914 // @LOCALMOD-END |
857 if (TheTriple.getEnvironment() == Triple::GNUX32) | 915 if (TheTriple.getEnvironment() == Triple::GNUX32) |
858 return new ELFX86_X32AsmBackend(T, OSABI, CPU); | 916 return new ELFX86_X32AsmBackend(T, OSABI, CPU); |
859 return new ELFX86_64AsmBackend(T, OSABI, CPU); | 917 return new ELFX86_64AsmBackend(T, OSABI, CPU); |
860 } | 918 } |
OLD | NEW |