#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFragment.h"
+#include "llvm/Support/Endian.h"
#include <cstdint>
#include <memory>
std::unique_ptr<MCCodePadder> CodePadder;
protected: // Can only create subclasses.
- MCAsmBackend();
- MCAsmBackend(std::unique_ptr<MCCodePadder> TargetCodePadder);
+ MCAsmBackend(support::endianness Endian);
public:
MCAsmBackend(const MCAsmBackend &) = delete;
MCAsmBackend &operator=(const MCAsmBackend &) = delete;
virtual ~MCAsmBackend();
+ const support::endianness Endian;
+
/// lifetime management
virtual void reset() {}
/// target cannot generate such a sequence, it should return an error.
///
/// \return - True on success.
- virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
+ virtual bool writeNopData(raw_ostream &OS, uint64_t Count) const = 0;
/// Give backend an opportunity to finish layout after relaxation
virtual void finishLayout(MCAssembler const &Asm,
using namespace llvm;
-MCAsmBackend::MCAsmBackend() : CodePadder(new MCCodePadder()) {}
-
-MCAsmBackend::MCAsmBackend(std::unique_ptr<MCCodePadder> TargetCodePadder)
- : CodePadder(std::move(TargetCodePadder)) {}
+MCAsmBackend::MCAsmBackend(support::endianness Endian)
+ : CodePadder(new MCCodePadder()), Endian(Endian) {}
MCAsmBackend::~MCAsmBackend() = default;
// ----------------------------
// ^-------------------^ <- TotalLength
unsigned DistanceToBoundary = TotalLength - getBundleAlignSize();
- if (!getBackend().writeNopData(DistanceToBoundary, OW))
+ if (!getBackend().writeNopData(OW->getStream(), DistanceToBoundary))
report_fatal_error("unable to write NOP sequence of " +
Twine(DistanceToBoundary) + " bytes");
BundlePadding -= DistanceToBoundary;
}
- if (!getBackend().writeNopData(BundlePadding, OW))
+ if (!getBackend().writeNopData(OW->getStream(), BundlePadding))
report_fatal_error("unable to write NOP sequence of " +
Twine(BundlePadding) + " bytes");
}
// bytes left to fill use the Value and ValueSize to fill the rest.
// If we are aligning with nops, ask that target to emit the right data.
if (AF.hasEmitNops()) {
- if (!Asm.getBackend().writeNopData(Count, OW))
+ if (!Asm.getBackend().writeNopData(OW->getStream(), Count))
report_fatal_error("unable to write nop sequence of " +
Twine(Count) + " bytes");
break;
}
case MCFragment::FT_Padding: {
- if (!Asm.getBackend().writeNopData(FragmentSize, OW))
+ if (!Asm.getBackend().writeNopData(OW->getStream(), FragmentSize))
report_fatal_error("unable to write nop sequence of " +
Twine(FragmentSize) + " bytes");
break;
Triple TheTriple;
public:
- bool IsLittleEndian;
-
-public:
AArch64AsmBackend(const Target &T, const Triple &TT, bool IsLittleEndian)
- : MCAsmBackend(), TheTriple(TT), IsLittleEndian(IsLittleEndian) {}
+ : MCAsmBackend(IsLittleEndian ? support::little : support::big),
+ TheTriple(TT) {}
unsigned getNumFixupKinds() const override {
return AArch64::NumTargetFixupKinds;
const MCAsmLayout &Layout) const override;
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override;
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
/// getFixupKindContainereSizeInBytes - The number of bytes of the
/// container involved in big endian or 0 if the item is little endian
unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) const {
- if (IsLittleEndian)
+ if (Endian == support::little)
return 0;
switch (Kind) {
llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented");
}
-bool AArch64AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
// If the count is not 4-byte aligned, we must be writing data into the text
// section (otherwise we have unaligned instructions, and thus have far
// bigger problems), so just write zeros instead.
- OW->WriteZeros(Count % 4);
+ OS.write_zeros(Count % 4);
// We are properly aligned, so write NOPs as requested.
Count /= 4;
for (uint64_t i = 0; i != Count; ++i)
- OW->write32(0xd503201f);
+ support::endian::write<uint32_t>(OS, 0xd503201f, Endian);
return true;
}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
- return createAArch64ELFObjectWriter(OS, OSABI, IsLittleEndian, IsILP32);
+ return createAArch64ELFObjectWriter(OS, OSABI,
+ Endian == support::little, IsILP32);
}
};
class AMDGPUAsmBackend : public MCAsmBackend {
public:
- AMDGPUAsmBackend(const Target &T)
- : MCAsmBackend() {}
+ AMDGPUAsmBackend(const Target &T) : MCAsmBackend(support::little) {}
unsigned getNumFixupKinds() const override { return AMDGPU::NumTargetFixupKinds; };
bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
unsigned getMinimumNopSize() const override;
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
};
return 4;
}
-bool AMDGPUAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool AMDGPUAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
// If the count is not 4-byte aligned, we must be writing data into the text
// section (otherwise we have unaligned instructions, and thus have far
// bigger problems), so just write zeros instead.
- OW->WriteZeros(Count % 4);
+ OS.write_zeros(Count % 4);
// We are properly aligned, so write NOPs as requested.
Count /= 4;
const uint32_t Encoded_S_NOP_0 = 0xbf800000;
for (uint64_t I = 0; I != Count; ++I)
- OW->write32(Encoded_S_NOP_0);
+ support::endian::write<uint32_t>(OS, Encoded_S_NOP_0, Endian);
return true;
}
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/TargetParser.h"
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
"Invalid kind!");
- return (IsLittleEndian ? InfosLE : InfosBE)[Kind - FirstTargetFixupKind];
+ return (Endian == support::little ? InfosLE
+ : InfosBE)[Kind - FirstTargetFixupKind];
}
void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) {
Res.setOpcode(RelaxedOp);
}
-bool ARMAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool ARMAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8
const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP
const uint32_t ARMv4_NopEncoding = 0xe1a00000; // using MOV r0,r0
hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
uint64_t NumNops = Count / 2;
for (uint64_t i = 0; i != NumNops; ++i)
- OW->write16(nopEncoding);
+ support::endian::write(OS, nopEncoding, Endian);
if (Count & 1)
- OW->write8(0);
+ OS << '\0';
return true;
}
// ARM mode
hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
uint64_t NumNops = Count / 4;
for (uint64_t i = 0; i != NumNops; ++i)
- OW->write32(nopEncoding);
+ support::endian::write(OS, nopEncoding, Endian);
// FIXME: should this function return false when unable to write exactly
// 'Count' bytes with NOP encodings?
switch (Count % 4) {
default:
break; // No leftover bytes to write
case 1:
- OW->write8(0);
+ OS << '\0';
break;
case 2:
- OW->write16(0);
+ OS.write("\0\0", 2);
break;
case 3:
- OW->write16(0);
- OW->write8(0xa0);
+ OS.write("\0\0\xa0", 3);
break;
}
// inst{14-12} = Mid3;
// inst{7-0} = Lo8;
Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
- return swapHalfWords(Value, IsLittleEndian);
+ return swapHalfWords(Value, Endian == support::little);
}
case ARM::fixup_arm_ldst_pcrel_12:
// ARM PC-relative values are offset by 8.
// Same addressing mode as fixup_arm_pcrel_10,
// but with 16-bit halfwords swapped.
if (Kind == ARM::fixup_t2_ldst_pcrel_12)
- return swapHalfWords(Value, IsLittleEndian);
+ return swapHalfWords(Value, Endian == support::little);
return Value;
}
out |= (Value & 0x700) << 4;
out |= (Value & 0x0FF);
- return swapHalfWords(out, IsLittleEndian);
+ return swapHalfWords(out, Endian == support::little);
}
case ARM::fixup_arm_condbranch:
out |= (Value & 0x1FF800) << 5; // imm6 field
out |= (Value & 0x0007FF); // imm11 field
- return swapHalfWords(out, IsLittleEndian);
+ return swapHalfWords(out, Endian == support::little);
}
case ARM::fixup_t2_condbranch: {
Value = Value - 4;
out |= (Value & 0x1F800) << 5; // imm6 field
out |= (Value & 0x007FF); // imm11 field
- return swapHalfWords(out, IsLittleEndian);
+ return swapHalfWords(out, Endian == support::little);
}
case ARM::fixup_arm_thumb_bl: {
// FIXME: We get both thumb1 and thumb2 in here, so we can only check for
uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
(uint16_t)imm11Bits);
- return joinHalfWords(FirstHalf, SecondHalf, IsLittleEndian);
+ return joinHalfWords(FirstHalf, SecondHalf, Endian == support::little);
}
case ARM::fixup_arm_thumb_blx: {
// The value doesn't encode the low two bits (always zero) and is offset by
uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
((uint16_t)imm10LBits) << 1);
- return joinHalfWords(FirstHalf, SecondHalf, IsLittleEndian);
+ return joinHalfWords(FirstHalf, SecondHalf, Endian == support::little);
}
case ARM::fixup_thumb_adr_pcrel_10:
case ARM::fixup_arm_thumb_cp:
// Same addressing mode as fixup_arm_pcrel_10, but with 16-bit halfwords
// swapped.
if (Kind == ARM::fixup_t2_pcrel_10)
- return swapHalfWords(Value, IsLittleEndian);
+ return swapHalfWords(Value, Endian == support::little);
return Value;
}
// Same addressing mode as fixup_arm_pcrel_9, but with 16-bit halfwords
// swapped.
if (Kind == ARM::fixup_t2_pcrel_9)
- return swapHalfWords(Value, IsLittleEndian);
+ return swapHalfWords(Value, Endian == support::little);
return Value;
}
EncValue |= (Value & 0x800) << 15;
EncValue |= (Value & 0x700) << 4;
EncValue |= (Value & 0xff);
- return swapHalfWords(EncValue, IsLittleEndian);
+ return swapHalfWords(EncValue, Endian == support::little);
}
}
}
// Used to point to big endian bytes.
unsigned FullSizeBytes;
- if (!IsLittleEndian) {
+ if (Endian == support::big) {
FullSizeBytes = getFixupKindContainerSizeBytes(Fixup.getKind());
assert((Offset + FullSizeBytes) <= Data.size() && "Invalid fixup size!");
assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
// the fixup value. The Value has been "split up" into the appropriate
// bitfields above.
for (unsigned i = 0; i != NumBytes; ++i) {
- unsigned Idx = IsLittleEndian ? i : (FullSizeBytes - 1 - i);
+ unsigned Idx = Endian == support::little ? i : (FullSizeBytes - 1 - i);
Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
}
}
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options,
- bool isLittle) {
+ support::endianness Endian) {
const Triple &TheTriple = STI.getTargetTriple();
switch (TheTriple.getObjectFormat()) {
default:
case Triple::ELF:
assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target");
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
- return new ARMAsmBackendELF(T, STI, OSABI, isLittle);
+ return new ARMAsmBackendELF(T, STI, OSABI, Endian);
}
}
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
- return createARMAsmBackend(T, STI, MRI, Options, true);
+ return createARMAsmBackend(T, STI, MRI, Options, support::little);
}
MCAsmBackend *llvm::createARMBEAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
- return createARMAsmBackend(T, STI, MRI, Options, false);
+ return createARMAsmBackend(T, STI, MRI, Options, support::big);
}
class ARMAsmBackend : public MCAsmBackend {
const MCSubtargetInfo &STI;
bool isThumbMode; // Currently emitting Thumb code.
- bool IsLittleEndian; // Big or little endian.
public:
- ARMAsmBackend(const Target &T, const MCSubtargetInfo &STI, bool IsLittle)
- : MCAsmBackend(), STI(STI),
- isThumbMode(STI.getTargetTriple().isThumb()),
- IsLittleEndian(IsLittle) {}
+ ARMAsmBackend(const Target &T, const MCSubtargetInfo &STI,
+ support::endianness Endian)
+ : MCAsmBackend(Endian), STI(STI),
+ isThumbMode(STI.getTargetTriple().isThumb()) {}
unsigned getNumFixupKinds() const override {
return ARM::NumTargetFixupKinds;
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override;
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
void handleAssemblerFlag(MCAssemblerFlag Flag) override;
unsigned getPointerSize() const { return 4; }
bool isThumb() const { return isThumbMode; }
void setIsThumb(bool it) { isThumbMode = it; }
- bool isLittle() const { return IsLittleEndian; }
};
} // end namespace llvm
const MachO::CPUSubTypeARM Subtype;
ARMAsmBackendDarwin(const Target &T, const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI, MachO::CPUSubTypeARM st)
- : ARMAsmBackend(T, STI, /* IsLittleEndian */ true), MRI(MRI),
- Subtype(st) {}
+ : ARMAsmBackend(T, STI, support::little), MRI(MRI), Subtype(st) {}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
public:
uint8_t OSABI;
ARMAsmBackendELF(const Target &T, const MCSubtargetInfo &STI, uint8_t OSABI,
- bool IsLittle)
- : ARMAsmBackend(T, STI, IsLittle), OSABI(OSABI) {}
+ support::endianness Endian)
+ : ARMAsmBackend(T, STI, Endian), OSABI(OSABI) {}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
- return createARMELFObjectWriter(OS, OSABI, isLittle());
+ return createARMELFObjectWriter(OS, OSABI, Endian);
}
};
}
class ARMAsmBackendWinCOFF : public ARMAsmBackend {
public:
ARMAsmBackendWinCOFF(const Target &T, const MCSubtargetInfo &STI)
- : ARMAsmBackend(T, STI, true) {}
+ : ARMAsmBackend(T, STI, support::little) {}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
return createARMWinCOFFObjectWriter(OS, /*Is64Bit=*/false);
return Infos[Kind - FirstTargetFixupKind];
}
-bool AVRAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool AVRAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
// If the count is not 2-byte aligned, we must be writing data into the text
// section (otherwise we have unaligned instructions, and thus have far
// bigger problems), so just write zeros instead.
assert((Count % 2) == 0 && "NOP instructions must be 2 bytes");
- OW->WriteZeros(Count);
+ OS.write_zeros(Count);
return true;
}
/// Utilities for manipulating generated AVR machine code.
class AVRAsmBackend : public MCAsmBackend {
public:
-
AVRAsmBackend(Triple::OSType OSType)
- : MCAsmBackend(), OSType(OSType) {}
+ : MCAsmBackend(support::little), OSType(OSType) {}
void adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
uint64_t &Value, MCContext *Ctx = nullptr) const;
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override {}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target) override;
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/EndianStream.h"
#include <cassert>
#include <cstdint>
class BPFAsmBackend : public MCAsmBackend {
public:
- bool IsLittleEndian;
-
- BPFAsmBackend(bool IsLittleEndian)
- : MCAsmBackend(), IsLittleEndian(IsLittleEndian) {}
+ BPFAsmBackend(support::endianness Endian) : MCAsmBackend(Endian) {}
~BPFAsmBackend() override = default;
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override {}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
};
} // end anonymous namespace
-bool BPFAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool BPFAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
if ((Count % 8) != 0)
return false;
for (uint64_t i = 0; i < Count; i += 8)
- OW->write64(0x15000000);
+ support::endian::write<uint64_t>(OS, 0x15000000, Endian);
return true;
}
bool IsResolved) const {
if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) {
assert(Value == 0);
- } else if (Fixup.getKind() == FK_Data_4 || Fixup.getKind() == FK_Data_8) {
- unsigned Size = Fixup.getKind() == FK_Data_4 ? 4 : 8;
-
- for (unsigned i = 0; i != Size; ++i) {
- unsigned Idx = IsLittleEndian ? i : Size - i - 1;
- Data[Fixup.getOffset() + Idx] = uint8_t(Value >> (i * 8));
- }
+ } else if (Fixup.getKind() == FK_Data_4) {
+ support::endian::write<uint32_t>(&Data[Fixup.getOffset()], Value, Endian);
+ } else if (Fixup.getKind() == FK_Data_8) {
+ support::endian::write<uint64_t>(&Data[Fixup.getOffset()], Value, Endian);
} else if (Fixup.getKind() == FK_PCRel_4) {
Value = (uint32_t)((Value - 8) / 8);
- if (IsLittleEndian) {
+ if (Endian == support::little) {
Data[Fixup.getOffset() + 1] = 0x10;
support::endian::write32le(&Data[Fixup.getOffset() + 4], Value);
} else {
} else {
assert(Fixup.getKind() == FK_PCRel_2);
Value = (uint16_t)((Value - 8) / 8);
- if (IsLittleEndian) {
- Data[Fixup.getOffset() + 2] = Value & 0xFF;
- Data[Fixup.getOffset() + 3] = Value >> 8;
- } else {
- Data[Fixup.getOffset() + 2] = Value >> 8;
- Data[Fixup.getOffset() + 3] = Value & 0xFF;
- }
+ support::endian::write<uint16_t>(&Data[Fixup.getOffset() + 2], Value,
+ Endian);
}
}
std::unique_ptr<MCObjectWriter>
BPFAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
- return createBPFELFObjectWriter(OS, 0, IsLittleEndian);
+ return createBPFELFObjectWriter(OS, 0, Endian == support::little);
}
MCAsmBackend *llvm::createBPFAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &) {
- return new BPFAsmBackend(/*IsLittleEndian=*/true);
+ return new BPFAsmBackend(support::little);
}
MCAsmBackend *llvm::createBPFbeAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &) {
- return new BPFAsmBackend(/*IsLittleEndian=*/false);
+ return new BPFAsmBackend(support::big);
}
public:
HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
- StringRef CPU) :
- OSABI(OSABI), CPU(CPU), MCII(T.createMCInstrInfo()),
- RelaxTarget(new MCInst *), Extender(nullptr) {}
+ StringRef CPU)
+ : MCAsmBackend(support::little), OSABI(OSABI), CPU(CPU),
+ MCII(T.createMCInstrInfo()), RelaxTarget(new MCInst *),
+ Extender(nullptr) {}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
assert(Update && "Didn't find relaxation target");
}
- bool writeNopData(uint64_t Count,
- MCObjectWriter * OW) const override {
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP.
ParseIn = 0x00004000, // In packet parse-bits.
ParseEnd = 0x0000c000; // End of packet parse-bits.
<< Count % HEXAGON_INSTR_SIZE << "/"
<< HEXAGON_INSTR_SIZE << "\n");
--Count;
- OW->write8(0);
+ OS << '\0';
}
while(Count) {
// Close the packet whenever a multiple of the maximum packet size remains
uint32_t ParseBits = (Count % (HEXAGON_PACKET_SIZE * HEXAGON_INSTR_SIZE))?
ParseIn: ParseEnd;
- OW->write32(Nopcode | ParseBits);
+ support::endian::write<uint32_t>(OS, Nopcode | ParseBits, Endian);
}
return true;
}
public:
LanaiAsmBackend(const Target &T, Triple::OSType OST)
- : MCAsmBackend(), OSType(OST) {}
+ : MCAsmBackend(support::big), OSType(OST) {}
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
const MCSubtargetInfo & /*STI*/,
MCInst & /*Res*/) const override {}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
};
-bool LanaiAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool LanaiAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
if ((Count % 4) != 0)
return false;
for (uint64_t i = 0; i < Count; i += 4)
- OW->write32(0x15000000);
+ OS.write("\x15\0\0\0", 4);
return true;
}
bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
for (unsigned i = 0; i != NumBytes; ++i) {
- unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
- : i)
- : (FullSize - 1 - i);
+ unsigned Idx = Endian == support::little
+ ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
+ : (FullSize - 1 - i);
CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
}
// Write out the fixed up bytes back to the code/data bits.
for (unsigned i = 0; i != NumBytes; ++i) {
- unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
- : i)
- : (FullSize - 1 - i);
+ unsigned Idx = Endian == support::little
+ ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
+ : (FullSize - 1 - i);
Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
}
}
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
"Invalid kind!");
- if (IsLittle)
+ if (Endian == support::little)
return LittleEndianInfos[Kind - FirstTargetFixupKind];
return BigEndianInfos[Kind - FirstTargetFixupKind];
}
/// it should return an error.
///
/// \return - True on success.
-bool MipsAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
// Check for a less than instruction size number of bytes
// FIXME: 16 bit instructions are not handled yet here.
// We shouldn't be using a hard coded number for instruction size.
// If the count is not 4-byte aligned, we must be writing data into the text
// section (otherwise we have unaligned instructions, and thus have far
// bigger problems), so just write zeros instead.
- OW->WriteZeros(Count);
+ OS.write_zeros(Count);
return true;
}
class MipsAsmBackend : public MCAsmBackend {
Triple TheTriple;
- bool IsLittle; // Big or little endian
bool IsN32;
public:
MipsAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT,
StringRef CPU, bool N32)
- : TheTriple(TT), IsLittle(TT.isLittleEndian()), IsN32(N32) {}
+ : MCAsmBackend(TT.isLittleEndian() ? support::little : support::big),
+ TheTriple(TT), IsN32(N32) {}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override;
/// @}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
}; // class MipsAsmBackend
MCELFObjectTargetWriter::getOSABI(OSType));
}
-bool Nios2AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool Nios2AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
return true;
}
public:
Nios2AsmBackend(const Target &T, Triple::OSType OSType)
- : MCAsmBackend(), OSType(OSType) {}
+ : MCAsmBackend(support::little), OSType(OSType) {}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override;
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
class PPCAsmBackend : public MCAsmBackend {
const Target &TheTarget;
- bool IsLittleEndian;
public:
- PPCAsmBackend(const Target &T, bool isLittle) : MCAsmBackend(), TheTarget(T),
- IsLittleEndian(isLittle) {}
+ PPCAsmBackend(const Target &T, support::endianness Endian)
+ : MCAsmBackend(Endian), TheTarget(T) {}
unsigned getNumFixupKinds() const override {
return PPC::NumTargetFixupKinds;
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
"Invalid kind!");
- return (IsLittleEndian? InfosLE : InfosBE)[Kind - FirstTargetFixupKind];
+ return (Endian == support::little
+ ? InfosLE
+ : InfosBE)[Kind - FirstTargetFixupKind];
}
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
// from the fixup value. The Value has been "split up" into the appropriate
// bitfields above.
for (unsigned i = 0; i != NumBytes; ++i) {
- unsigned Idx = IsLittleEndian ? i : (NumBytes - 1 - i);
+ unsigned Idx = Endian == support::little ? i : (NumBytes - 1 - i);
Data[Offset + i] |= uint8_t((Value >> (Idx * 8)) & 0xff);
}
}
llvm_unreachable("relaxInstruction() unimplemented");
}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override {
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
uint64_t NumNops = Count / 4;
for (uint64_t i = 0; i != NumNops; ++i)
- OW->write32(0x60000000);
+ support::endian::write<uint32_t>(OS, 0x60000000, Endian);
- OW->WriteZeros(Count % 4);
+ OS.write_zeros(Count % 4);
return true;
}
assert(Name == "ppc32" && "Unknown target name!");
return 4;
}
-
- bool isLittleEndian() const {
- return IsLittleEndian;
- }
};
} // end anonymous namespace
namespace {
class DarwinPPCAsmBackend : public PPCAsmBackend {
public:
- DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T, false) { }
+ DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T, support::big) { }
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
class ELFPPCAsmBackend : public PPCAsmBackend {
uint8_t OSABI;
public:
- ELFPPCAsmBackend(const Target &T, bool IsLittleEndian, uint8_t OSABI) :
- PPCAsmBackend(T, IsLittleEndian), OSABI(OSABI) { }
+ ELFPPCAsmBackend(const Target &T, support::endianness Endian,
+ uint8_t OSABI)
+ : PPCAsmBackend(T, Endian), OSABI(OSABI) {}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
bool is64 = getPointerSize() == 8;
- return createPPCELFObjectWriter(OS, is64, isLittleEndian(), OSABI);
+ return createPPCELFObjectWriter(OS, is64, Endian == support::little,
+ OSABI);
}
};
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
bool IsLittleEndian = TT.getArch() == Triple::ppc64le;
- return new ELFPPCAsmBackend(T, IsLittleEndian, OSABI);
+ return new ELFPPCAsmBackend(
+ T, IsLittleEndian ? support::little : support::big, OSABI);
}
public:
RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit)
- : MCAsmBackend(), STI(STI), OSABI(OSABI), Is64Bit(Is64Bit) {}
+ : MCAsmBackend(support::little), STI(STI), OSABI(OSABI),
+ Is64Bit(Is64Bit) {}
~RISCVAsmBackend() override {}
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
MCInst &Res) const override;
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
};
return getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode();
}
-bool RISCVAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
bool HasStdExtC = STI.getFeatureBits()[RISCV::FeatureStdExtC];
unsigned MinNopLen = HasStdExtC ? 2 : 4;
// The canonical nop on RISC-V is addi x0, x0, 0.
uint64_t Nop32Count = Count / 4;
for (uint64_t i = Nop32Count; i != 0; --i)
- OW->write32(0x13);
+ OS.write("\x13\0\0\0", 4);
// The canonical nop on RVC is c.nop.
if (HasStdExtC) {
uint64_t Nop16Count = (Count - Nop32Count * 4) / 2;
for (uint64_t i = Nop16Count; i != 0; --i)
- OW->write16(0x01);
+ OS.write("\x01\0", 2);
}
return true;
class SparcAsmBackend : public MCAsmBackend {
protected:
const Target &TheTarget;
- bool IsLittleEndian;
bool Is64Bit;
public:
SparcAsmBackend(const Target &T)
- : MCAsmBackend(), TheTarget(T),
- IsLittleEndian(StringRef(TheTarget.getName()) == "sparcel"),
- Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {}
+ : MCAsmBackend(StringRef(T.getName()) == "sparcel" ? support::little
+ : support::big),
+ TheTarget(T), Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {}
unsigned getNumFixupKinds() const override {
return Sparc::NumTargetFixupKinds;
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
"Invalid kind!");
- if (IsLittleEndian)
+ if (Endian == support::little)
return InfosLE[Kind - FirstTargetFixupKind];
return InfosBE[Kind - FirstTargetFixupKind];
llvm_unreachable("relaxInstruction() unimplemented");
}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override {
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
// Cannot emit NOP with size not multiple of 32 bits.
if (Count % 4 != 0)
return false;
uint64_t NumNops = Count / 4;
for (uint64_t i = 0; i != NumNops; ++i)
- OW->write32(0x01000000);
+ support::endian::write<uint32_t>(OS, 0x01000000, Endian);
return true;
}
// from the fixup value. The Value has been "split up" into the
// appropriate bitfields above.
for (unsigned i = 0; i != 4; ++i) {
- unsigned Idx = IsLittleEndian ? i : 3 - i;
+ unsigned Idx = Endian == support::little ? i : 3 - i;
Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
}
}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
- return createSparcELFObjectWriter(OS, Is64Bit, IsLittleEndian, OSABI);
+ return createSparcELFObjectWriter(OS, Is64Bit,
+ Endian == support::little, OSABI);
}
};
uint8_t OSABI;
public:
SystemZMCAsmBackend(uint8_t osABI)
- : OSABI(osABI) {}
+ : MCAsmBackend(support::big), OSABI(osABI) {}
// Override MCAsmBackend
unsigned getNumFixupKinds() const override {
MCInst &Res) const override {
llvm_unreachable("SystemZ does do not have assembler relaxation");
}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override {
return createSystemZObjectWriter(OS, OSABI);
}
}
-bool SystemZMCAsmBackend::writeNopData(uint64_t Count,
- MCObjectWriter *OW) const {
+bool SystemZMCAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
for (uint64_t I = 0; I != Count; ++I)
- OW->write8(7);
+ OS << '\x7';
return true;
}
public:
explicit WebAssemblyAsmBackendELF(bool Is64Bit)
- : MCAsmBackend(), Is64Bit(Is64Bit) {}
+ : MCAsmBackend(support::little), Is64Bit(Is64Bit) {}
~WebAssemblyAsmBackendELF() override {}
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override {}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
};
class WebAssemblyAsmBackend final : public MCAsmBackend {
public:
explicit WebAssemblyAsmBackend(bool Is64Bit)
- : MCAsmBackend(), Is64Bit(Is64Bit) {}
+ : MCAsmBackend(support::little), Is64Bit(Is64Bit) {}
~WebAssemblyAsmBackend() override {}
unsigned getNumFixupKinds() const override {
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override {}
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
};
-bool WebAssemblyAsmBackendELF::writeNopData(uint64_t Count,
- MCObjectWriter *OW) const {
+bool WebAssemblyAsmBackendELF::writeNopData(raw_ostream &OS,
+ uint64_t Count) const {
for (uint64_t i = 0; i < Count; ++i)
- OW->write8(WebAssembly::Nop);
+ OS << char(WebAssembly::Nop);
return true;
}
return Infos[Kind - FirstTargetFixupKind];
}
-bool WebAssemblyAsmBackend::writeNopData(uint64_t Count,
- MCObjectWriter *OW) const {
+bool WebAssemblyAsmBackend::writeNopData(raw_ostream &OS,
+ uint64_t Count) const {
if (Count == 0)
return true;
for (uint64_t i = 0; i < Count; ++i)
- OW->write8(WebAssembly::Nop);
+ OS << char(WebAssembly::Nop);
return true;
}
const MCSubtargetInfo &STI;
public:
X86AsmBackend(const Target &T, const MCSubtargetInfo &STI)
- : MCAsmBackend(), STI(STI) {}
+ : MCAsmBackend(support::little), STI(STI) {}
unsigned getNumFixupKinds() const override {
return X86::NumTargetFixupKinds;
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override;
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
};
} // end anonymous namespace
/// Write a sequence of optimal nops to the output, covering \p Count
/// bytes.
/// \return - true on success, false on failure
-bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
- static const uint8_t Nops[10][10] = {
+bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
+ static const char Nops[10][11] = {
// nop
- {0x90},
+ "\x90",
// xchg %ax,%ax
- {0x66, 0x90},
+ "\x66\x90",
// nopl (%[re]ax)
- {0x0f, 0x1f, 0x00},
+ "\x0f\x1f\x00",
// nopl 0(%[re]ax)
- {0x0f, 0x1f, 0x40, 0x00},
+ "\x0f\x1f\x40\x00",
// nopl 0(%[re]ax,%[re]ax,1)
- {0x0f, 0x1f, 0x44, 0x00, 0x00},
+ "\x0f\x1f\x44\x00\x00",
// nopw 0(%[re]ax,%[re]ax,1)
- {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
+ "\x66\x0f\x1f\x44\x00\x00",
// nopl 0L(%[re]ax)
- {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
+ "\x0f\x1f\x80\x00\x00\x00\x00",
// nopl 0L(%[re]ax,%[re]ax,1)
- {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+ "\x0f\x1f\x84\x00\x00\x00\x00\x00",
// nopw 0L(%[re]ax,%[re]ax,1)
- {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+ "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00",
// nopw %cs:0L(%[re]ax,%[re]ax,1)
- {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+ "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
};
// This CPU doesn't support long nops. If needed add more.
// FIXME: We could generated something better than plain 0x90.
if (!STI.getFeatureBits()[X86::FeatureNOPL]) {
for (uint64_t i = 0; i < Count; ++i)
- OW->write8(0x90);
+ OS << '\x90';
return true;
}
const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength);
const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
for (uint8_t i = 0; i < Prefixes; i++)
- OW->write8(0x66);
+ OS << '\x66';
const uint8_t Rest = ThisNopLength - Prefixes;
- for (uint8_t i = 0; i < Rest; i++)
- OW->write8(Nops[Rest - 1][i]);
+ OS.write(Nops[Rest - 1], Rest);
Count -= ThisNopLength;
} while (Count != 0);