brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · 72bb372 Raw
288 lines · cpp
1//===- SystemZHLASMAsmStreamer.cpp - HLASM Assembly Text 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#include "SystemZHLASMAsmStreamer.h"10#include "llvm/ADT/StringExtras.h"11#include "llvm/Support/Casting.h"12#include "llvm/Support/Signals.h"13#include <sstream>14 15using namespace llvm;16 17void SystemZHLASMAsmStreamer::EmitEOL() {18  // Comments are emitted on a new line before the instruction.19  if (IsVerboseAsm)20    EmitComment();21 22  std::istringstream Stream(Str);23  SmallVector<std::string> Lines;24  std::string Line;25  while (std::getline(Stream, Line, '\n'))26    Lines.push_back(Line);27 28  for (auto S : Lines) {29    if (LLVM_LIKELY(S.length() < ContIndicatorColumn)) {30      FOS << S;31      // Each line in HLASM must fill the full 80 characters.32      FOS.PadToColumn(InstLimit);33      FOS << "\n";34    } else {35      // If last character before end of the line is not a space36      // we must insert an additional non-space character that37      // is not part of the statement coding. We just reuse38      // the existing character by making the new substring start39      // 1 character sooner, thus "duplicating" that character40      // If The last character is a space. We insert an X instead.41      std::string TmpSubStr = S.substr(0, ContIndicatorColumn);42      if (!TmpSubStr.compare(ContIndicatorColumn - 1, 1, " "))43        TmpSubStr.replace(ContIndicatorColumn - 1, 1, "X");44 45      FOS << TmpSubStr;46      FOS.PadToColumn(InstLimit);47      FOS << "\n";48 49      size_t Emitted = ContIndicatorColumn - 1;50 51      while (Emitted < S.length()) {52        if ((S.length() - Emitted) < ContLen)53          TmpSubStr = S.substr(Emitted, S.length());54        else {55          TmpSubStr = S.substr(Emitted, ContLen);56          if (!TmpSubStr.compare(ContLen - 1, 1, " "))57            TmpSubStr.replace(ContLen - 1, 1, "X");58        }59        FOS.PadToColumn(ContStartColumn);60        FOS << TmpSubStr;61        FOS.PadToColumn(InstLimit);62        FOS << "\n";63        Emitted += ContLen - 1;64      }65    }66  }67  Str.clear();68}69 70void SystemZHLASMAsmStreamer::changeSection(MCSection *Section,71                                            uint32_t Subsection) {72  MAI->printSwitchToSection(*Section, Subsection,73                            getContext().getTargetTriple(), OS);74  MCStreamer::changeSection(Section, Subsection);75}76 77void SystemZHLASMAsmStreamer::emitAlignmentDS(uint64_t ByteAlignment,78                                              std::optional<int64_t> Value,79                                              unsigned ValueSize,80                                              unsigned MaxBytesToEmit) {81  if (!isPowerOf2_64(ByteAlignment))82    report_fatal_error("Only power-of-two alignments are supported ");83 84  OS << " DS 0";85  switch (ValueSize) {86  default:87    llvm_unreachable("Invalid size for machine code value!");88  case 1:89    OS << "B";90    break;91  case 2:92    OS << "H";93    break;94  case 4:95    OS << "F";96    break;97  case 8:98    OS << "D";99    break;100  case 16:101    OS << "Q";102    break;103  }104 105  EmitEOL();106}107 108void SystemZHLASMAsmStreamer::AddComment(const Twine &T, bool EOL) {109  if (!IsVerboseAsm)110    return;111 112  T.toVector(CommentToEmit);113 114  if (EOL)115    CommentToEmit.push_back('\n'); // Place comment in a new line.116}117 118void SystemZHLASMAsmStreamer::EmitComment() {119  if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0)120    return;121 122  StringRef Comments = CommentToEmit;123 124  assert(Comments.back() == '\n' && "Comment array not newline terminated");125  do {126    // Emit a line of comments, but not exceeding 80 characters.127    size_t Position = std::min(InstLimit - 2, Comments.find('\n'));128    FOS << MAI->getCommentString() << ' ' << Comments.substr(0, Position)129        << '\n';130 131    if (Comments[Position] == '\n')132      Position++;133    Comments = Comments.substr(Position);134  } while (!Comments.empty());135 136  CommentToEmit.clear();137}138 139void SystemZHLASMAsmStreamer::emitValueToAlignment(Align Alignment,140                                                   int64_t Fill,141                                                   uint8_t FillLen,142                                                   unsigned MaxBytesToEmit) {143  emitAlignmentDS(Alignment.value(), Fill, FillLen, MaxBytesToEmit);144}145 146void SystemZHLASMAsmStreamer::emitCodeAlignment(Align Alignment,147                                                const MCSubtargetInfo *STI,148                                                unsigned MaxBytesToEmit) {149  // Emit with a text fill value.150  if (MAI->getTextAlignFillValue())151    emitAlignmentDS(Alignment.value(), MAI->getTextAlignFillValue(), 1,152                    MaxBytesToEmit);153  else154    emitAlignmentDS(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);155}156 157void SystemZHLASMAsmStreamer::emitBytes(StringRef Data) {158  assert(getCurrentSectionOnly() &&159         "Cannot emit contents before setting section!");160  if (Data.empty())161    return;162 163  OS << " DC ";164  size_t Len = Data.size();165  SmallVector<uint8_t> Chars;166  Chars.resize(Len);167  OS << "XL" << Len;168  uint32_t Index = 0;169  for (uint8_t C : Data) {170    Chars[Index] = C;171    Index++;172  }173 174  OS << '\'' << toHex(Chars) << '\'';175 176  EmitEOL();177}178 179void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,180                                              const MCSubtargetInfo &STI) {181 182  InstPrinter->printInst(&Inst, 0, "", STI, OS);183  EmitEOL();184}185 186void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {187 188  MCStreamer::emitLabel(Symbol, Loc);189 190  Symbol->print(OS, MAI);191  // TODO Need to adjust this based on Label type192  OS << " DS 0H";193  // TODO Update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been194  // moved to HLASM syntax.195  // OS << MAI->getLabelSuffix();196  EmitEOL();197}198 199void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {200  String.consume_back("\n");201  OS << String;202  EmitEOL();203}204 205// Slight duplicate of MCExpr::print due to HLASM only recognizing limited206// arithmetic operators (+-*/).207void SystemZHLASMAsmStreamer::emitHLASMValueImpl(const MCExpr *Value,208                                                 unsigned Size, bool Parens) {209  switch (Value->getKind()) {210  case MCExpr::Constant: {211    OS << "XL" << Size << '\'';212    MAI->printExpr(OS, *Value);213    OS << '\'';214    return;215  }216  case MCExpr::Binary: {217    const MCBinaryExpr &BE = cast<MCBinaryExpr>(*Value);218    int64_t Const;219    // Or is handled differently.220    if (BE.getOpcode() == MCBinaryExpr::Or) {221      emitHLASMValueImpl(BE.getLHS(), Size, true);222      OS << ',';223      emitHLASMValueImpl(BE.getRHS(), Size, true);224      return;225    }226 227    if (Parens)228      OS << "A(";229    emitHLASMValueImpl(BE.getLHS(), Size);230 231    switch (BE.getOpcode()) {232    case MCBinaryExpr::LShr: {233      Const = cast<MCConstantExpr>(BE.getRHS())->getValue();234      OS << '/' << (1 << Const);235      if (Parens)236        OS << ')';237      return;238    }239    case MCBinaryExpr::Add:240      OS << '+';241      break;242    case MCBinaryExpr::Div:243      OS << '/';244      break;245    case MCBinaryExpr::Mul:246      OS << '*';247      break;248    case MCBinaryExpr::Sub:249      OS << '-';250      break;251    default:252      getContext().reportError(SMLoc(),253                               "Unrecognized HLASM arithmetic expression!");254    }255    emitHLASMValueImpl(BE.getRHS(), Size);256    if (Parens)257      OS << ')';258    return;259  }260  case MCExpr::Target:261    MAI->printExpr(OS, *Value);262    return;263  default:264    if (Parens)265      OS << "A(";266    MAI->printExpr(OS, *Value);267    if (Parens)268      OS << ')';269    return;270  }271}272 273void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,274                                            SMLoc Loc) {275  assert(Size <= 8 && "Invalid size");276  assert(getCurrentSectionOnly() &&277         "Cannot emit contents before setting section!");278 279  OS << " DC ";280  emitHLASMValueImpl(Value, Size, true);281  EmitEOL();282}283 284void SystemZHLASMAsmStreamer::emitEnd() {285  OS << " END";286  EmitEOL();287}288