brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 2a6da4c Raw
75 lines · cpp
1//===-------- PPCXCOFFStreamer.cpp - XCOFF Object Output ------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This is a custom MCXCOFFStreamer for PowerPC.10//11// The purpose of the custom XCOFF streamer is to allow us to intercept12// instructions as they are being emitted and align all 8 byte instructions13// to a 64 byte boundary if required (by adding a 4 byte nop). This is important14// because 8 byte instructions are not allowed to cross 64 byte boundaries15// and by aligning anything that is within 4 bytes of the boundary we can16// guarantee that the 8 byte instructions do not cross that boundary.17//18//===----------------------------------------------------------------------===//19 20#include "PPCXCOFFStreamer.h"21#include "PPCMCCodeEmitter.h"22#include "llvm/MC/MCAsmBackend.h"23#include "llvm/MC/MCAssembler.h"24#include "llvm/MC/MCCodeEmitter.h"25#include "llvm/MC/MCObjectWriter.h"26#include "llvm/MC/TargetRegistry.h"27 28using namespace llvm;29 30PPCXCOFFStreamer::PPCXCOFFStreamer(MCContext &Context,31                                   std::unique_ptr<MCAsmBackend> MAB,32                                   std::unique_ptr<MCObjectWriter> OW,33                                   std::unique_ptr<MCCodeEmitter> Emitter)34    : MCXCOFFStreamer(Context, std::move(MAB), std::move(OW),35                      std::move(Emitter)) {}36 37void PPCXCOFFStreamer::emitPrefixedInstruction(const MCInst &Inst,38                                               const MCSubtargetInfo &STI) {39  // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is40  // before the boundary and the remaining 4-bytes are after the boundary). In41  // order to achieve this, a nop is added prior to any such boundary-crossing42  // prefixed instruction. Align to 64 bytes if possible but add a maximum of 443  // bytes when trying to do that. If alignment requires adding more than 444  // bytes then the instruction won't be aligned.45  emitCodeAlignment(Align(64), &STI, 4);46 47  // Emit the instruction.48  // Since the previous emit created a new fragment then adding this instruction49  // also forces the addition of a new fragment. Inst is now the first50  // instruction in that new fragment.51  MCXCOFFStreamer::emitInstruction(Inst, STI);52}53 54void PPCXCOFFStreamer::emitInstruction(const MCInst &Inst,55                                       const MCSubtargetInfo &STI) {56  PPCMCCodeEmitter *Emitter =57      static_cast<PPCMCCodeEmitter *>(getAssembler().getEmitterPtr());58 59  // Special handling is only for prefixed instructions.60  if (!Emitter->isPrefixedInstruction(Inst)) {61    MCXCOFFStreamer::emitInstruction(Inst, STI);62    return;63  }64  emitPrefixedInstruction(Inst, STI);65}66 67MCStreamer *68llvm::createPPCXCOFFStreamer(const Triple &, MCContext &C,69                             std::unique_ptr<MCAsmBackend> &&MAB,70                             std::unique_ptr<MCObjectWriter> &&OW,71                             std::unique_ptr<MCCodeEmitter> &&Emitter) {72  return new PPCXCOFFStreamer(C, std::move(MAB), std::move(OW),73                              std::move(Emitter));74}75