Path: blob/main/contrib/llvm-project/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
213845 views
//===- SystemZHLASMAsmStreamer.cpp - HLASM Assembly Text 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//===----------------------------------------------------------------------===//78#include "SystemZHLASMAsmStreamer.h"9#include "llvm/ADT/StringExtras.h"10#include "llvm/Support/Casting.h"11#include "llvm/Support/Signals.h"12#include <sstream>1314using namespace llvm;1516void SystemZHLASMAsmStreamer::EmitEOL() {17// Comments are emitted on a new line before the instruction.18if (IsVerboseAsm)19EmitComment();2021std::istringstream Stream(Str);22SmallVector<std::string> Lines;23std::string Line;24while (std::getline(Stream, Line, '\n'))25Lines.push_back(Line);2627for (auto S : Lines) {28if (LLVM_LIKELY(S.length() < ContIndicatorColumn)) {29FOS << S;30// Each line in HLASM must fill the full 80 characters.31FOS.PadToColumn(InstLimit);32FOS << "\n";33} else {34// If last character before end of the line is not a space35// we must insert an additional non-space character that36// is not part of the statement coding. We just reuse37// the existing character by making the new substring start38// 1 character sooner, thus "duplicating" that character39// If The last character is a space. We insert an X instead.40std::string TmpSubStr = S.substr(0, ContIndicatorColumn);41if (!TmpSubStr.compare(ContIndicatorColumn - 1, 1, " "))42TmpSubStr.replace(ContIndicatorColumn - 1, 1, "X");4344FOS << TmpSubStr;45FOS.PadToColumn(InstLimit);46FOS << "\n";4748size_t Emitted = ContIndicatorColumn - 1;4950while (Emitted < S.length()) {51if ((S.length() - Emitted) < ContLen)52TmpSubStr = S.substr(Emitted, S.length());53else {54TmpSubStr = S.substr(Emitted, ContLen);55if (!TmpSubStr.compare(ContLen - 1, 1, " "))56TmpSubStr.replace(ContLen - 1, 1, "X");57}58FOS.PadToColumn(ContStartColumn);59FOS << TmpSubStr;60FOS.PadToColumn(InstLimit);61FOS << "\n";62Emitted += ContLen - 1;63}64}65}66Str.clear();67}6869void SystemZHLASMAsmStreamer::changeSection(MCSection *Section,70uint32_t Subsection) {71Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,72Subsection);73MCStreamer::changeSection(Section, Subsection);74}7576void SystemZHLASMAsmStreamer::emitAlignmentDS(uint64_t ByteAlignment,77std::optional<int64_t> Value,78unsigned ValueSize,79unsigned MaxBytesToEmit) {80if (!isPowerOf2_64(ByteAlignment))81report_fatal_error("Only power-of-two alignments are supported ");8283OS << " DS 0";84switch (ValueSize) {85default:86llvm_unreachable("Invalid size for machine code value!");87case 1:88OS << "B";89break;90case 2:91OS << "H";92break;93case 4:94OS << "F";95break;96case 8:97OS << "D";98break;99case 16:100OS << "Q";101break;102}103104EmitEOL();105}106107void SystemZHLASMAsmStreamer::AddComment(const Twine &T, bool EOL) {108if (!IsVerboseAsm)109return;110111T.toVector(CommentToEmit);112113if (EOL)114CommentToEmit.push_back('\n'); // Place comment in a new line.115}116117void SystemZHLASMAsmStreamer::EmitComment() {118if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0)119return;120121StringRef Comments = CommentToEmit;122123assert(Comments.back() == '\n' && "Comment array not newline terminated");124do {125// Emit a line of comments, but not exceeding 80 characters.126size_t Position = std::min(InstLimit - 2, Comments.find('\n'));127FOS << MAI->getCommentString() << ' ' << Comments.substr(0, Position)128<< '\n';129130if (Comments[Position] == '\n')131Position++;132Comments = Comments.substr(Position);133} while (!Comments.empty());134135CommentToEmit.clear();136}137138void SystemZHLASMAsmStreamer::emitValueToAlignment(Align Alignment,139int64_t Fill,140uint8_t FillLen,141unsigned MaxBytesToEmit) {142emitAlignmentDS(Alignment.value(), Fill, FillLen, MaxBytesToEmit);143}144145void SystemZHLASMAsmStreamer::emitCodeAlignment(Align Alignment,146const MCSubtargetInfo *STI,147unsigned MaxBytesToEmit) {148// Emit with a text fill value.149if (MAI->getTextAlignFillValue())150emitAlignmentDS(Alignment.value(), MAI->getTextAlignFillValue(), 1,151MaxBytesToEmit);152else153emitAlignmentDS(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);154}155156void SystemZHLASMAsmStreamer::emitBytes(StringRef Data) {157assert(getCurrentSectionOnly() &&158"Cannot emit contents before setting section!");159if (Data.empty())160return;161162OS << " DC ";163size_t Len = Data.size();164SmallVector<uint8_t> Chars;165Chars.resize(Len);166OS << "XL" << Len;167uint32_t Index = 0;168for (uint8_t C : Data) {169Chars[Index] = C;170Index++;171}172173OS << '\'' << toHex(Chars) << '\'';174175EmitEOL();176}177178void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,179const MCSubtargetInfo &STI) {180181InstPrinter->printInst(&Inst, 0, "", STI, OS);182EmitEOL();183}184185void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {186187MCStreamer::emitLabel(Symbol, Loc);188189Symbol->print(OS, MAI);190// TODO Need to adjust this based on Label type191OS << " DS 0H";192// TODO Update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been193// moved to HLASM syntax.194// OS << MAI->getLabelSuffix();195EmitEOL();196}197198void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {199String.consume_back("\n");200OS << String;201EmitEOL();202}203204// Slight duplicate of MCExpr::print due to HLASM only recognizing limited205// arithmetic operators (+-*/).206void SystemZHLASMAsmStreamer::emitHLASMValueImpl(const MCExpr *Value,207unsigned Size, bool Parens) {208switch (Value->getKind()) {209case MCExpr::Constant: {210OS << "XL" << Size << '\'';211MAI->printExpr(OS, *Value);212OS << '\'';213return;214}215case MCExpr::Binary: {216const MCBinaryExpr &BE = cast<MCBinaryExpr>(*Value);217int64_t Const;218// Or is handled differently.219if (BE.getOpcode() == MCBinaryExpr::Or) {220emitHLASMValueImpl(BE.getLHS(), Size, true);221OS << ',';222emitHLASMValueImpl(BE.getRHS(), Size, true);223return;224}225226if (Parens)227OS << "A(";228emitHLASMValueImpl(BE.getLHS(), Size);229230switch (BE.getOpcode()) {231case MCBinaryExpr::LShr: {232Const = cast<MCConstantExpr>(BE.getRHS())->getValue();233OS << '/' << (1 << Const);234if (Parens)235OS << ')';236return;237}238case MCBinaryExpr::Add:239OS << '+';240break;241case MCBinaryExpr::Div:242OS << '/';243break;244case MCBinaryExpr::Mul:245OS << '*';246break;247case MCBinaryExpr::Sub:248OS << '-';249break;250default:251getContext().reportError(SMLoc(),252"Unrecognized HLASM arithmetic expression!");253}254emitHLASMValueImpl(BE.getRHS(), Size);255if (Parens)256OS << ')';257return;258}259case MCExpr::Target:260MAI->printExpr(OS, *Value);261return;262default:263if (Parens)264OS << "A(";265MAI->printExpr(OS, *Value);266if (Parens)267OS << ')';268return;269}270}271272void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,273SMLoc Loc) {274assert(Size <= 8 && "Invalid size");275assert(getCurrentSectionOnly() &&276"Cannot emit contents before setting section!");277278OS << " DC ";279emitHLASMValueImpl(Value, Size, true);280EmitEOL();281}282283void SystemZHLASMAsmStreamer::emitEnd() {284OS << " END";285EmitEOL();286}287288289