Path: blob/main/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFStreamer.cpp
35294 views
//===-------- PPCXCOFFStreamer.cpp - XCOFF Object Output ------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This is a custom MCXCOFFStreamer for PowerPC.9//10// The purpose of the custom XCOFF streamer is to allow us to intercept11// instructions as they are being emitted and align all 8 byte instructions12// to a 64 byte boundary if required (by adding a 4 byte nop). This is important13// because 8 byte instructions are not allowed to cross 64 byte boundaries14// and by aligning anything that is within 4 bytes of the boundary we can15// guarantee that the 8 byte instructions do not cross that boundary.16//17//===----------------------------------------------------------------------===//1819#include "PPCXCOFFStreamer.h"20#include "PPCMCCodeEmitter.h"21#include "llvm/BinaryFormat/XCOFF.h"22#include "llvm/MC/MCAsmBackend.h"23#include "llvm/MC/MCAssembler.h"24#include "llvm/MC/MCCodeEmitter.h"25#include "llvm/MC/MCDirectives.h"26#include "llvm/MC/MCObjectWriter.h"27#include "llvm/MC/MCSectionXCOFF.h"28#include "llvm/MC/MCSymbolXCOFF.h"29#include "llvm/MC/TargetRegistry.h"3031using namespace llvm;3233PPCXCOFFStreamer::PPCXCOFFStreamer(MCContext &Context,34std::unique_ptr<MCAsmBackend> MAB,35std::unique_ptr<MCObjectWriter> OW,36std::unique_ptr<MCCodeEmitter> Emitter)37: MCXCOFFStreamer(Context, std::move(MAB), std::move(OW),38std::move(Emitter)) {}3940void PPCXCOFFStreamer::emitPrefixedInstruction(const MCInst &Inst,41const MCSubtargetInfo &STI) {42// Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is43// before the boundary and the remaining 4-bytes are after the boundary). In44// order to achieve this, a nop is added prior to any such boundary-crossing45// prefixed instruction. Align to 64 bytes if possible but add a maximum of 446// bytes when trying to do that. If alignment requires adding more than 447// bytes then the instruction won't be aligned.48emitCodeAlignment(Align(64), &STI, 4);4950// Emit the instruction.51// Since the previous emit created a new fragment then adding this instruction52// also forces the addition of a new fragment. Inst is now the first53// instruction in that new fragment.54MCXCOFFStreamer::emitInstruction(Inst, STI);55}5657void PPCXCOFFStreamer::emitInstruction(const MCInst &Inst,58const MCSubtargetInfo &STI) {59PPCMCCodeEmitter *Emitter =60static_cast<PPCMCCodeEmitter *>(getAssembler().getEmitterPtr());6162// Special handling is only for prefixed instructions.63if (!Emitter->isPrefixedInstruction(Inst)) {64MCXCOFFStreamer::emitInstruction(Inst, STI);65return;66}67emitPrefixedInstruction(Inst, STI);68}6970MCXCOFFStreamer *71llvm::createPPCXCOFFStreamer(MCContext &Context,72std::unique_ptr<MCAsmBackend> MAB,73std::unique_ptr<MCObjectWriter> OW,74std::unique_ptr<MCCodeEmitter> Emitter) {75return new PPCXCOFFStreamer(Context, std::move(MAB), std::move(OW),76std::move(Emitter));77}787980